IF / ELSE depending on result of stored procedure - sql

I've the following stored procedure:
ALTER PROCEDURE [dbo].[CheckAdminExists]
#SID NVARCHAR(50),
#AdminName NVARCHAR(MAX)
AS
SELECT
Administrator.ID
FROM
Administrator
WHERE
Administrator.SID = #SID
AND Administrator.Name = #AdminName
GO
Now I would like to create another SP with a code like that:
IF NOT NULL (EXECUTE CheckAdminExists 'S-1','Admin')
--do something
ELSE
--do something else
What's the right syntax for doing it?

You should not use a stored procedure for this and use a function instead to check if the Admin Exists.
Then in your new stored procedure call the CheckAdminExists function:
CREATE FUNCTION [dbo].[CheckAdminExists] (#SID NVARCHAR(50), #AdminName NVARCHAR(MAX))
RETURNS BIT
AS
BEGIN
DECLARE #RetVal INT
SELECT #RetVal = COUNT(Administrator.ID)
FROM
Administrator
WHERE
Administrator.SID = #SID
AND Administrator.Name = #AdminName
IF #RetVal > 0
BEGIN
RETURN 1
END
RETURN 0
END
Then in your stored procedure call the function:
DECLARE #AdminExists BIT
SELECT #AdminExists = [dbo].[CheckAdminExists]
IF #AdminExists
BEGIN
-- your code
END
ELSE
BEGIN
-- your code
END

Indeed, use FUNCTION.
But if you need to return more than 1, use OUTPUT parameters.

Related

Calling stored procedure from other stored procedure

This is stored procedure #1:
ALTER PROCEDURE [dbo].[sp1]
AS
BEGIN
DECLARE #test varchar(255)
exec #test = dbo.sp2
SET NOCOUNT ON;
SELECT
CMS_ORG.description, #test
FROM
CMS_ORG
END
This is stored procedure #2:
ALTER PROCEDURE [dbo].[sp2]
AS
BEGIN
SET NOCOUNT ON;
SELECT
CMS_MAS.description + '' + CONVERT(varchar(50),
CAST(CMS_ORG.amount AS money), 1)
FROM
CMS_ORG
INNER JOIN
CMS_MAS = CMS_ORG.GUID = CMS_MAS.GUID
END
The problem is here is I was not able to execute #test in stored procedure #1 by calling the stored procedure #2. When I execute sp1, I got a null values instead but when I execute the query of sp2 in sp1, I got a correct value. May I know what is the possible solution or similar examples which can solve the issue?
Your stored proc sp2 outputs the result of a SELECT, but like all stored procs, it returns an integer using the return statement. You don't have a return statement, so Sql Server generates one for you: return 0. The purpose of the return code is to give feedback on whether it ran as expected. By convention, a return code of 0 means no errors.
This shows the difference between the return code and the output of a stored proc. Create a temp table #output to capture the rows of the SELECT that the stored proc outputs.
DECLARE #return_code int
-- capture the output of the stored proc sp2 in a temp table
create table #output( column_data varchar(max) )
insert #output( column_data )
exec #return_code = dbo.sp2 -- returns 0 because you have no RETURN statement
-- extract column_data from #output into variable #test
-- if there is more than one row in #output, it will take the last one
DECLARE #test varchar(255)
select #test = column_data from #output
Create a table variable & Use it like this :
create proc test55
as
select 55
declare #test table (Value Varchar(255))
insert into #test
exec test55
Select * from #test
Your sp2 stored procedure will return table, not varchar(255).
If you want to get a varchar(255) from sp2 you should be using function.
You can view in my example:
Define a function:
CREATE FUNCTION dbo.function1()
RETURNS varchar(255)
WITH EXECUTE AS CALLER
AS
BEGIN
DECLARE #returnVal varchar(255);
SET #returnVal = (SELECT top 1 [ProductName]
FROM [dbo].[Products])
RETURN(#returnVal);
END;
And alter SP1 like this:
ALTER PROCEDURE [dbo].[sp1]
#SMonth As Integer,
#SYear As Integer
AS
BEGIN
DECLARE #test varchar(255)
set #test = dbo.function1()
SET NOCOUNT ON;
SELECT [ProductId], #test
FROM [LearningKO].[dbo].[Products]
END

user defined function call vs calling UDF in a Store procedure

I have a user defined function that is called inside a stored procedure. All that stored procedure does is return the value that is obtained from the UDF scalar function.
However,
Select * UDF_FunctionName(param1,param2)
udf call is here-
SELECT dbo.udfFunction('1234',10) as result
and
Exec StoreProcName(param1,param2)
are returning different results.
StoreProcName calls the `UDF_FunctionName(param1,param2)
sproc code is here-
BEGIN
SET NOCOUNT ON;
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
END
What could be the reason for different results?.
You are trying to use RETURN and SELECT together:
Return SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
You cannot do that, you either want to return the result, or select it. Depending on which you choose, retrieving the value will differ.
If you do this:
SELECT [DbName].[dbo].[udfFunction](#param1, #param2)
Then the resultset will have a single row and column containing your value. Access this exactly as you would any other resultset.
If you do this:
RETURN [DbName].[dbo].[udfFunction](#param1, #param2)
Your stored procedure will have a return value which is the result of your function call. Access this by defining a scalar variable and assigning it to the result of the SP call - assuming the result is INT that might look like
DECLARE #result INT
EXEC #Result = StoredProcName(#param1, #param2)
You should not use RETURN in this way in a stored procedure. If you want to return a scalar value to the calling code use an OUTPUT parameter. RETURN is generally used for status codes.
You might have something like
-- SAMPLE UDF
CREATE FUNCTION dbo.YourUDF (#Username VARCHAR(30), #EntityID INT)
RETURNS INT
AS
BEGIN
RETURN #EntityID;
END
GO
-- SAMPLE PROCEDURE
CREATE PROCEDURE dbo.YourProc #Username VARCHAR(30), #EntityID INT, #Output INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #Output = dbo.YourUDF(#Username, #EntityID);
IF #Output IS NULL -- AN ERROR
BEGIN
RETURN 1; -- RETURN A STATUS OF -1 TO INDICATE ERROR
END
END
Then you could call this as:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = 1,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
This returns:
ValueFromUDF ReturnValue
------------------------------
1 0
If we pass NULL as #EntityID, to trigger the artificial error, then we get a return status of -1:
DECLARE #Output INT, #ReturnValue INT;
EXECUTE #ReturnValue = dbo.YourProc
#Username = '1234',
#EntityID = NULL,
#Output = #Output OUTPUT;
SELECT ValueFromUDF = #Output,
ReturnValue = #ReturnValue;
ValueFromUDF ReturnValue
------------------------------
NULL 1

Get scalar value from SELECT statement in stored proc, from within a stored proc

I know the preferred method for returning scalar values from stored procs is either using RETURN or an OUTPUT parameter. But lets say that I have a stored proc that returns the value using a select statement:
CREATE PROC spReturnNumber AS
SELECT 1
Is it possible to get this value from within another stored proc?
CREATE PROC spCheckNumber AS
EXEC spReturnNumber -- <-- get the return value here?
Clarification: I need a solution that doesn't require using an OUTPUT parameter, or using RETURN to return the value.
Thanks in advance.
You could use insert-exec to store the result of a stored procedure in a table:
declare #t table (col1 int)
insert #t exec spReturnNumber
return (select col1 from #t)
The definition of the table has to match the result set of the stored procedure.
Use an OUTPUT parameter instead of (or in addition to, if this procedure is used by other applications) the SELECT.
ALTER PROCEDURE dbo.spReturnNumber
#Number INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SET #Number = 1;
SELECT #Number;
END
GO
CREATE PROCEDURE dbo.spCheckNumber
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Number INT;
EXEC dbo.spReturnNumber #Number = #Number;
SELECT #Number;
END
GO
If you can't change the original procedure, but you know its output will remain static, you could use a #temp table.
CREATE PROCEDURE dbo.spCheckNumber
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #n(i INT);
INSERT #n(i) EXEC dbo.spReturnNumber;
DECLARE #Number INT;
SELECT #Number = i FROM #n;
END
GO
You can't get the SELECT value from "parent" procedure but you can get the return value like this:
CREATE PROC A AS
BEGIN
DECLARE #ret int
EXEC #ret = spReturnNumber
RETURN #ret
END
If you are unable to change the proc being called .. place the result set in a temp table [or table variable]:
CREATE TABLE #results (val INT)
DECLARE #someval int
INSERT #results
EXEC dbo.spCheckNumber
SELECT #someval =val from #results

How Can i Let Stored Procedure Returns Varchar Value?

Here is my sample:
ALTER PROCEDURE EmpFirstName
#myParam int,
#empFName varchar(20) output
AS
BEGIN
SET NOCOUNT ON;
SELECT #empFName = empfname
FROM FE_QEMP
WHERE empno = #myParam
END
GO
myParam is the input and empFName will carry the output, so the procedure
should only take 1 parameter since empFName is the output, but in my case
i get this error:
Msg 201, Level 16, State 4, Procedure
EmpFirstName, Line 0 Procedure or
function 'EmpFirstName' expects
parameter '#empFName', which was not
supplied.
This is the way i called the procedure:
DECLARE #returnValue varchar(20)
EXEC #returnValue = EmpFirstName 10
SELECT 'Return Value ' = #returnValue
Return values and output parameters are two different things. If you want to call it with an output parameter, you'd do it like this:
EXEC EmpFirstName 10, #returnValue OUTPUT
SELECT 'Return Value ' + #returnValue
If you want to call it in the manner that you described in your example, then you need to alter the stored procedure to state RETURNS VARCHAR(20) and remove the output parameter. To return a value, you have to explicitly call return. In your example, you'd declare a variable, assign it in the select statement, then call return #varName.
Thanks. My aha moment came with this post. Did not realise that output parameters need to be qualified with the "output" identifier too when executed, not just in the procedure!
Here are my test workings for my fellow sql server noobs. I am using sqlcmd with sql server 2005.
The stored procedure:
/* :r procTest.sql */
if exists (select name from sysobjects where name="procTest" and type="P")
drop procedure procTest;
go
create procedure procTest
/* Test stored procedure elements. */
(#i_pt_varchar varchar(20),
#o_pt_varchar varchar(20) output)
as
begin
print "procTest";
set #o_pt_varchar = "string coming out";
print "#i_pt_varchar " + #i_pt_varchar;
print "#o_pt_varchar " + #o_pt_varchar;
return (0);
end
go
The test call:
/* :r procTest.test.sql */
declare #returnFlag int;
declare #i_varchar varchar(20);
declare #o_varchar varchar(20);
set #i_varchar = "string going in";
set #o_varchar = null;
execute #returnFlag = procTest #i_varchar, #o_varchar output
print "#returnFlag " + cast(#returnFlag as varchar(20));
print "after call";
print "#i_varchar " + #i_varchar;
print "#o_varchar " + #o_varchar;
go

can we have a stored procedure with output parameters and return statement?

Can a stored procedure have output parameters and return statement? If so can anybody give me a simple example.thank you all.
Stored procedure can return integer type only in a return statement and can have any number of out parameters. See this for references supporting this.
Simplest eg of stored procedure
Return integer value from SP
CREATE procedure [sys].[sp_name]
(
#var1 bit = 0,
#publisher smallint
)
AS
BEGIN
IF #var1<> 0
RETURN (#publisher )
END
Using Out Parameter
CREATE PROCEDURE GetImmediateManager
#employeeID INT,
#managerID INT OUTPUT
AS
BEGIN
SELECT #managerID = ManagerID
FROM HumanResources.Employee
WHERE EmployeeID = #employeeID
END
You can use Transactions, Exception handling(try Catch), DDL and DML Queries, calling another stored procedure within one stored procedures and many more operations.
Please comments for more functionalities supported in stored procedure
If you mean the standard RETURN statement that gives an integer then yes
If you mean a UDF RETURN , then no. But a stored proc can have a normal SELECT
You are free to use both OUTPUT params and a single RETURN value:
CREATE PROCEDURE RaiseToPower (
#IN INT,
#OUT INT OUTPUT
)
AS
DECLARE #POWER INT
SET #POWER = 3
SET #OUT = POWER(#IN, #POWER)
RETURN #POWER
GO
/**/
DECLARE #POW INT, #RESULT INT
EXEC #POW = dbo.RaiseToPower 2, #RESULT OUTPUT
SELECT 2, 'raised to', #POW, 'is', #RESULT
>> 2 raised to 3 is 8
No. It is either a stored procedure or a scalar function.
A scalar function returns a value and takes 0 to n in parameters.
A stored procedure can take from 0 to n input parameters and can have 0 to n output parameters.