Return a single value and multiple OUT parameter in Stored Procedure - sql

I read an article about Stored Procedures which said:
A stored procedure can return a single values such as a number or text value or a result set
I am confused, because if we declare multiple OUT parameters, the we can have multiple output but it said that we can have only a single value?
EDIT:
This is The Article

In SQL Server, a stored procedure can actually return a value -- always an integer. This is usually a status value and is quite separate from the output parameters.
So you can can have:
execute #retval = usp_myproc #x1 output, #x2 output;
The returned value is generally not data, but a status.

That statement is not entirely correct.
There are three ways of returning data from a procedure to a calling program: result sets, output parameters, and return codes.
See Return Data from a Stored Procedure
This link will walk you through the 3 approaches.

Related

Get a specific column from a returned result of SP?

I have a stored procedure that returns a result, let's say it return rows of products. But each product status is not in our hand(can't get it). Our DBA just gave us another stored procedure to get the status of a product. We need to get individual product status by calling their SP. Let's say we have Product table,
CREATE TABLE PRODUCTS
(
ID INT,
Name NVARCHAR(100)
)
CREATE PROCEDURE GetProducts
AS
BEGIN
INSERT INTO #TEMPTABLE
SELECT * FROM PRODUCTS; -- Yes Too Much simplified
-- Create cursor and set additional status in #TEMPTABLE
END;
EXEC GetStatus #ProductId; -- SP That need to get status
The problem is that GetStatus is only way to get the status and this sp sometimes return 2 columns, sometimes 4 and sometimes 8. The return columns will always include Status column for sure.
If columns names is fixed then there is no problem. Is there is a way to create dynamic table at the time of executing SP.
Tried this but not working,
WITH DynamicTable AS
(
EXEC GetStatus
)
The answer to your question is no. There is no good way to get the value of a specific column returned by a stored procedure that can return a dynamic set of columns.
I say no "good" way, because of course there's a WAY. You can write an INSERT EXEC statement for every possible set of columns that the procedure can return and wrap each one in a TRY..CATCH block. If the first one errors, try the next one. As soon as you hit one that doesn't error, get the Status from it, and skip the rest.
That's the answer to your question. The solution to your problem, however, is to replace the GetStatus stored procedure with a Table-valued function. Then you can select from it, join to it, etc. I think the function would have to always return a consistent number of columns, but that would be better anyway, and the columns that aren't needed in a specific case could just be left empty or NULL.

Single variable consists of number of characters in stored procedure?

CREATE PROCEDURE Testing1
#Varaible nvarchar(50),
#value integer
AS
BEGIN
DECLARE #SUMM FLOAT
SET #SUMM=(#value*2.38/7.456)*2
PRINT #Varaible
PRINT 'EXPENSES IS'
PRINT #SUMM
END
Output is:
PETER
EXPENSES IS
24.2597
The above is my code where I am passing a single input parameter.
If I want to pass multiple values like peter,robber,licoln,mat
#varaible peter,robber,licoln,mat
#value 37 45 66 77
is it possible in SQL??
If you're only sending a few values in your delimited strings, I would suggest simply using the proper datatypes and calling the stored procedure a few times with individual values.
If, however, your delimited strings might contain hundreds or thousands of discrete values, then calling a proc that many times could be costly in terms of performance, especially if you can't send them all in one batch (I'm sure you want to use parameters rather than a giant concatenated command). If this is the case, you have a few options:
Use Table Valued Parameters. This is like passing arrays as arguments to your proc.
Pass XML to your proc, then shred and process it within the procedure.
Insert your data to staging/temp tables, then call the procedure to operate on those tables.
Take a step back and see if it makes sense to do more processing in your app. DB code usually doesn't scale nearly as well as app code.
Send these delimited strings to your proc, split/parse them, then loop over the results in SQL. This seems to be what you're asking about and is possibly the least elegant option, even though it's one of the more popular ways to abuse a relational database.
The table valued parameters approach seems very 'approachable', but is only available as of MSSQL 2008. If you are still stuck with MSSQL 2005 then, maybe, the temporary table approach works best for you?
Your code could look something like:
-- define your stored procedure
CREATE PROC sptest1 AS
BEGIN
-- do some stuff with #tmp, like join it to other tables
-- and UPDATE values in these tables with it!
-- or simply list a processed version of #tmp:
SELECT nam,val*(2.38/7.456)*2 FROM #tmp
END
-- prepare input values by creating a temporary table on the fly
SELECT 'Peter' nam,23 val INTO #tmp
UNION ALL SELECT 'Paul',27
UNION ALL SELECT 'Harry',16
UNION ALL SELECT 'Mary-Ann',45;
-- and call the procedure:
EXEC sptest1
So, your frontend will have to build the SELECT ... INTO #tmp ... string. After that the rest of the processing can be done inside your stored procedure.

How can a stored procedure return ROWCOUNT?

I have written stored procedure which has 2 Insert queries and 1 Update query inside it. Of all these,either insert queries or update query are executed at a time. Now my problem is to get ROWCOUNT in each case. Say suppose if insert operations are executed,then I want stored procedure to return ##ROWCOUNT to the calling application, so that the application will be aware of whether the required operations executed correctly or not. Can anyone suggest/tell me how can I get the rows affected from the stored procedure?
Use Output parameters in your stored procedures to return the RowCount of your inserts / updates.
Refer MSDN link for more information on how to use Output params
You can have multiple output params so you can have 2 different output params one each for your insert and the 3rd for your update statement.
Example:
CREATE PROCEDURE GetEmployeeData
#employeeID INT,
#managerID INT **OUTPUT**
AS
BEGIN
....
....
Additionally, you can always concatenate the rowcounts of your 2 Inserts / Update using delimiters and return them as one value eg: "10;0" - However that is the old fashioned and "I would not recommend" approach.
Also, you could create a table variable and return the table with rows = number of Inserts / updates and the value of the column = RowCount affected.

How to set the result of exec stored procedure to a variable?

I need to exec a stored procedure and store its scalar result to a local variable inside a stored procedure.
How to implement?
E.G.
CREATE PROCEDURE [dbo].GetNthNo AS
DECLARE #a INT
DECLARE #d INT
DECLARE #n INT
DECLARE #S INT
SET #S=EXEC spGetNthNo #a,#d,#n
SELECT #S
Please help.
Instead of:
SET #S=EXEC spGetNthNo #a,#d,#n
You need:
EXEC #S = spGetNthNo #a,#d,#n
And then within the procedure, you need something like:
RETURN 100
or:
RETURN #x
for the value you want for #S after the procedure executes.
You can also use output parameters. Combined example:
IF OBJECT_ID('tempdb..#example') IS NOT NULL DROP PROCEDURE #example
GO
CREATE PROCEDURE #example
#output_param INT OUTPUT
AS BEGIN
SET #output_param = 100
RETURN 200
END
GO
DECLARE #return INT, #param INT
EXEC #return = #example #output_param = #param OUTPUT
SELECT #return as [return value], #param as [output parameter]
Try something like that
CREATE PROCEDURE Test
#RetVal INT OUT
AS
BEGIN
SET #RetVal = 99
END
DECLARE #X INT
EXEC Test #X OUT
PRINT #X
Edit: [comment following posting of T-SQL snippet in question]
You seem to need a wrapper, around the spGetNthNo Stored Procedure, maybe because this existing procedure doesn't return its result in the way that is desired. An alternative to a wrapper may simply be to modify [ever so slightly] spGetNthNo itself, so it works as desired in the first place (provided the method is not currently in use with its existing API).
Regardless of whether the changes will be in the original SP or in a wrapper, there are two distinct ways of retrieving data from an SP:
With output variables (as shown above)
By having the SP return a "recordset", i.e. a table made of rows (records) and columns (fields). (This is done by having a SELECT statement towards the end of the SP, as show in the question snippet)
With the output variable approach, the data is readily placed in the variables by the time the SP returns. With the recordset apporach, the calling logic needs to "consume" the data returned, in a similar fashion that it would from a SELECT statement.
Aside from the way the returned data is consumed, there are a few differences between these approaches.
The most obvious one is that the "recordset" approach allows the returning more values: one would have to explicitly declare say 30 variables (with some naming convention aimed at helping with the two-dimensional nature of the table) to emulate a the returns of a SP which "SELECT TOP 10 a, b, c FROM myTable". Also the SP would have to explicitly set each of the these output variables.
Another related but more subtle difference is that the recordset approach allows returning a number of rows and columns that is undefined at the time of the call. The number and types of the variables do not need to be expressed beforehand, rather they come with the metadata surrounding the recordset.
In short: the output variable approach is more suited to return a fixed set of a few variables, such as status code, maximum or minim value (or other aggregate values and calculations), or also, a few fields from a expected single record. The Recordset approach is used when the purpose of the stored procedure is to effectively provide a table-like result, or when it returns very many values, such as a long [and evolving] list of aggregate values, etc.

Stored Procedure returning Multiple resultset

One Stored procedure returning multiple result sets and I need only the last result set, How do I achieve this without changing original procedure. am using the last reulst set in further processing in other Stored procedure.
if you are "filling" a dataset in c#, very simple, just use:
datasetobj.Tables[datasetobj.Tables.Count-1].Table
to get the DataTable
if doing this within sql procedures (i.e. one procedure calling another that returns multiple), best solution would be to use output variables. concept:
procedure1 returns multiple resultsets
when calling:
declare #table1 table (), #table2 table ()
exec procedure1 out #table1, out #table2