can we have a stored procedure with output parameters and return statement? - sql-server-2005

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.

Related

How to use stored procedure return value into an insert statement?

I have a stored procedure like
CREATE PROCEDURE GetSerial (#param1 int, #param2 int)
AS
BEGIN
-- do some insert/updates, so I can't use function
DECLARE #value AS int;
SET #value = 3;
return #value;
END
Now I declare a table variable
DECLARE #Serials AS TABLE
(
ID int,
Value int
)
Now I wanna fill this table like
INSERT INTO #Serials (ID, Value)
SELECT 1, GetSerial(1,2) -- *How can I call this?
So, can anyone help me how can i call the GetSerial stored procedure inside the SELECT statement to fill my table?
I recommend you avoid getting into this pattern/thinking, because stored procedures only return INTs, and those ints are really intended to describe how well the operation went, not a result/data from the operation. Example: 0 => failed, 1=> succeeded. Not GetAgeInYears() => 29
https://learn.microsoft.com/en-us/sql/relational-databases/stored-procedures/return-data-from-a-stored-procedure?view=sql-server-2017 has a lot of info and concrete examples but in your specific case you'd need to execute the procedure and capture the result code into a variable then insert that:
DECLARE #ret INT;
EXEC #ret = GetSerial(1,2);
INSERT INTO #Serials VALUES(1, #ret);
Really you'd be better off using an output parameter or resultset if you have many values to return. See the above link for more

How to call Stored Procedure from within a TVF?

I'd like to utilise an already written stored procedure having parameters and temp tables for a report with Power BI (DirectQuery).
I've tried to do so via table-valued function as shown below:
CREATE FUNCTION [rpt].[ufnPBI0002_KPI]
(#YearMonth nvarchar(20), -- = '2017-12'
#Products nvarchar(50), -- = '2,7,8'
#Regions nvarchar(50) -- = '1'
)
-----------------------------------------------------------------------
-- Return type
-----------------------------------------------------------------------
RETURNS TABLE
-----------------------------------------------------------------------
-- Begin
-----------------------------------------------------------------------
AS
BEGIN
-----------------------------------------------------------------------
-- Declare return table
-----------------------------------------------------------------------
DECLARE #Result AS TABLE
(
SalesRegionId INT
,TotalCAcount INT
,EffectiveCAcount INT
,NewCA INT
,Plan_Total_CA_count INT
,Plan_eCA_Count_All INT
,Plan_CA_Intake INT
,Plan_CA_PJ_count INT
,Plan_NV_Prod_PJ INT
,Plan_Avg_NV_All_per_eCA INT
,BusinessLoanSpecialistCount INT
,ProfiJuniors INT
,ActiveCAcount INT
,TerminatedCAcount INT
,NewNV INT
,NewNVPJ INT
,AvgNVeCA INT
,AvgNVProfiJuniors INT
)
--------------------------------------------------------------------------
-- Handle stored procedure result
--------------------------------------------------------------------------
INSERT INTO #Result
EXEC [rpt].[MR0002_KPI] #YearMonth, #Products, #Regions
--------------------------------------------------------------------------
-- Return the result
--------------------------------------------------------------------------
SELECT * FROM #Result
RETURN;
-----------------------------------------------------------------------
-- END
-----------------------------------------------------------------------
END
Which returns
Msg 102, Level 15, State 31, Procedure ufnPBI0002_KPI, Line 68 [Batch Start Line 0]
Incorrect syntax near 'BEGIN'
I think it would not be possible to call a stored procedure from a TFV, but would really appreciate any hints, how to utilise parametric stored procedure with PBI.
You can not call stored procedures from within a Function
User-defined functions cannot call a stored procedure, but can call an extended stored procedure.
Change the function to a stored procedure
When it comes to SSRS data sources, you do not have to use a function in your case, bit can just directly use a stored procedure:
EXEC [rpt].[MR0002_KPI] #YearMonth, #Products, #Regions
Just refresh a dataset, it should be able to detect available columns returned by SP.
Moreover, your initial approach would result (if TVM allows SP) to unnecessary inserts to #Result table variable, so it could cause extra load on TEMPDB

SQL - Save results from stored procedure to a variable

I have a stored procedure that I cannot change. And it returns a select value (integer).
It insert some values and return the new id - the last line of the stored procedure:
SELECT #newID
I am using the new ID but I don't want to display that value when I run the stored procedure.
So I use the following:
DECLARE #test INT
EXEC #test = Pr_My_Procedure 'NewGroupName'
SELECT #test
This executes successfully, but my variable #test is always = 0 when the actual value created and return for the stored procedure is an actual id number.
Why is my variable is not being assigned?
I have a work around (which is not really what I wanted but it works:
1 DECLARE #NewGroupID INT
2 EXEC Pr_My_Procedure 'NewGroupName'
3 SET #NewGroupID = (SELECT GroupID FROM DB..Groups WHERE GroupName = 'NewGroupName')
This works, but when running the stored procedure, I still get the GroupID generated being return on the results (line 2). I don't want to see that.
Is it possible to NOT return that select result from the procedure?
Thanks all for any advise!
When you do
exec #p = StoredProc
... you are dealing with the return value of the proc, not the result set of the proc. The default return value of a procedure is zero so that if you do not do an explicit RETURN in your procedure, it returns 0.
You can change the procedure to RETURN your ID, or add an output parameter.
-- Procedure which RETURNS the ID
create procedure StoredProc_WithReturn
as
return 10;
go
-- Procedure which uses output parameter instead.
create procedure StoredProc_WithOutput
#p int output
as
select #p = 12;
go
-- Now test both ways of returning a value
declare #p int = 0,
#po int = 0;
exec #p = StoredProc_WithReturn;
select #p;
exec StoredProc_WithOutput #po output;
select #po;
Since you cannot change the procedure, you can insert the result set of the procedure into a table, temporary table or table variable like so
create procedure StoredProc_WithSelect
as
select 10;
go
declare #pt table (a int);
insert #pt
exec StoredProc_WithSelect;
select a from #pt;
If you don't see result, you can use PRINT instead of SELECT. Try this:
DECLARE #test INT
EXEC #test = Pr_My_Procedure 'NewGroupName'
PRINT #test

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

Stored Procedure Output

I've got two stored procedures:
SP1
CREATE PROCEDURE GetAge
#Birthday datetime,
#BirthDayAge INT OUTPUT
AS
SELECT #BirthDayAge = YEAR(GETDATE()-DATEPART(dy, #Birthday) + 1)-YEAR(#Birthday);
SP2
CREATE PROCEDURE AgeProc
#Age int
AS
DECLARE #BirthDayAge INT;
EXEC GetAge #Age, #BirthDayAge OUTPUT
SELECT ... FROM ... WHERE #BirthdayAge = #Age;
For some reason or other, no results are being returned in the second procedure when tested. Am I doing something wrong in either of the stored procedures?
WHERE #BirthdayAge = #Age;
you are comparing 2 variables.
Shouldnt one of this be a table column?
also, you are passing an integer to a datetime, that may cause issues