I have written a stored procedure Where I have written a query to get userid. There is a separate database for every userid. So I am trying to run a select query based on this userid obtained from my previous select query in a loop.
And I am trying to assign the columns in this select query to variables declared and use them further. But I am not understanding how to assign these to variables as I am getting errors
USE DATABASE1
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [User].[update_client_details]
AS
DECLARE
#clientdata CURSOR,
#clientid INT,
#SQL VARCHAR(2000),
#uid INT
#isactive INT,
#createdDate Date
BEGIN
SET #clientdata = CURSOR FOR
SELECT clientuserid FROM User.queen_client
OPEN #clientdata
FETCH NEXT
FROM #clientdata INTO #clientid
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = N'SELECT #uid=userid, #isactive=isactive, #createdDate=createddate FROM ['+CAST(#clientid AS NVARCHAR(20))+'].User.queen_user';
EXEC (#SQL)
IF(#isactive = 1)
BEGIN
//do someting//
END
END
CLOSE #clientdata
DEALLOCATE #clientdata
END
if the execute the store procedure it is getting executed and not stopping. If I force stop the execution then I am getting the error as "must declare the scalar variable "uid""
Query Which I tried
EXEC sys.sp_executesql N'SELECT #uid=userid, #isactive=isactive, #createdDate=createddate FROM ' +QUOTENAME(#clientid)+'.QueenBase.queen_user', N'#clienid int, #uid int OUTPUT, #createDate date OUTPUT';
Variables only persist and exist within the scope that they are declared in. Therefore both the following batches will fail:
DECLARE #I int = 1;
EXEC (N'SELECT #i;');
GO
EXEC (N'DECLARE #I int = 1;');
SELECT #i;
When using dynamic SQL, don't use EXEC(#SQL);, use sp_executesql. Then you can parametrise the statement. For example:
DECLARE #I int = 1;
EXEC sys.sp_executesql N'SELECT #i;', N'#i int', #i;
This returns 1. If you need to return a value to the outer SQL, as a parameter, you need to use OUTPUT parameters:
DECLARE #I int = 10;
DECLARE #O int;
EXEC sys.sp_executesql N'SELECT #O = #I / 2;', N'#I int, #O int OUTPUT', #I, #O OUTPUT;
SELECT #O;
This assigns the value 5 to the variable #O (which is then selected).
Also, don't use N'...[' + #SomeVariable + N'] ...' to inject dynamic values, it's not injection safe. Use QUOTENAME: N'...' + QUOTENAME(#SomeVariable) + N'...'
Additional note. The fact that you need to do something like N'FROM ['+CAST(#clientid AS NVARCHAR(20))+'].User.queen_user' suggests a severe design flaw, but that's a different topic.
If you do fancy additional reading, I cover a lot of considerations you need to take into account in my article Dos and Don'ts of Dynamic SQL.
For your attempt, it's not working as you use an expression for the first parameter (not a literal or variable) and then don't pass any of the parameters you define:
DECLARE #SQL nvarchar(MAX) = N'SELECT #uid=userid, #isactive=isactive, #createdDate=createddate FROM ' +QUOTENAME(#clientid)+'.QueenBase.queen_user;';
EXEC sys.sp_executesql #SQL, N'#isactive int OUTPUT, #uid int OUTPUT, #createDate date OUTPUT', #isactive OUTPUT, #uid OUTPUT, #createDate OUTPUT;
I have this stored procedure in Microsoft SQL Server:
CREATE PROCEDURE display_user_name
#userID INT,
#user_name VARCHAR(250) OUTPUT
AS
SET NOCOUNT ON;
SELECT #user_name = first_name +' '+ last_name
FROM User_Table
WHERE userID = #userID;
RETURN #user_name
GO
and I get this error
Conversion failed when converting the varchar value 'john1 doe1' to data type int.
When I run the stored procedure, I see that it creates a variable #return_value and it declares it as INT, this is the code that is generated when I right click and run the stored procedure
DECLARE #return_value INT,
#user_name VARCHAR(250)
EXEC #return_value = [dbo].[display_user_name]
#userID = 1,
#user_name = #user_name OUTPUT
SELECT #user_name as N'#user_name'
SELECT 'Return Value' = #return_value
GO
How will I need to modify my original stored procedure so I don't get this error?
Thanks for the help.
I'm trying to find out how to return the output parameter of a stored procedure when executing the stored procedure inside another stored procedure:
CREATE PROCEDURE Test1
EXEC SpWithOutputID -- Outputs #ID
SELECT #ID as ID -- Output #ID now being used in this SP
This is of course not my code, but just an example, is it possible to do this?
Example 2:
--Here #ID returns Null
CREATE PROCEDURE Test1
As
DECLARE #ID int
EXEC SpWithOutputID #ID = #ID OUTPUT -- Outputs #ID
SELECT #ID as ID -- Output #ID now being used in this SP
Example 3:
--Here #ID returns an Int
CREATE PROCEDURE Test1
As
EXEC SpWithOutputID -- Outputs #ID
If this isn't really an output parameter issue at all, but rather a result set, then taking a guess that SpWithOutputID does something like this (returns a SELECT with a single row and single column):
CREATE PROCEDURE dbo.SpWithOutputID
AS
BEGIN
SET NOCOUNT ON;
SELECT ID = 4;
END
GO
Then Test1 could look like this:
CREATE PROCEDURE dbo.Test1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ID INT;
CREATE TABLE #x(ID INT);
INSERT #x EXEC dbo.SpWithOutputID;
SELECT TOP (1) #ID = ID FROM #x;
DROP TABLE #x;
END
GO
But doesn't that look really messy to you? It really should work this way for single, scalar values:
CREATE PROCEDURE dbo.SpWithOutputID
#ID INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT #ID = 4;
END
GO
Now it is much simpler to consume what is really an output parameter now:
CREATE PROCEDURE dbo.Test1
AS
BEGIN
SET NOCOUNT ON;
DECLARE #ID INT;
EXEC dbo.SpWithOutputID #ID = #ID OUTPUT;
SELECT #ID;
END
GO
if i want to write a procedure like below, is there some other way that,
to avoid using concatenate SQL statement, i am just afraid, if the input is too long, exceed the limit of max varchar, the code will have big problem.
Thanks
CREATE PROCEDURE UPDATE_ALL_STATUS
#IDs varchar(MAX) = null,
#status int = null
AS
BEGIN
IF #IDs is null
BEGIN
RETURN
END
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'UPDATE mytable SET status = ' + #status + ' WHERE id in (' + #IDs + ')'
EXECUTE #SQL
END
Instead of dynamic SQL (which is also vulnerable to SQL Injection Attacks) and passing in a VARCHAR(MAX), consider using Table Valued Parameters:
-- Creates the TVP type - only needed once!
CREATE TYPE IntegerTableType AS TABLE
( Identities INT );
GO
CREATE PROCEDURE UPDATE_ALL_STATUS
#IDs IntegerTableType READONLY,
#status int = null
AS
BEGIN
UPDATE mytable
SET status = #status
WHERE id IN
(SELECT Identities FROM #IDs)
END
This MSDN article shows how to call these from your .NET code.
I have a stored procedure that I am trying to test. I am trying to test it through SQL Management Studio. In order to run this test I enter ...
exec my_stored_procedure 'param1Value', 'param2Value'
The final parameter is an output parameter. However, I do not know how to test a stored procedure with output parameters.
How do I run a stored procedure with an output parameter?
The easy way is to right-click on the procedure in Sql Server Management Studio (SSMS), select 'Execute stored procedure..." and add values for the input parameters as prompted. SSMS will then generate the code to run the procedure in a new query window, and execute it for you. You can study the generated code to see how it is done.
you can do this :
declare #rowCount int
exec yourStoredProcedureName #outputparameterspOf = #rowCount output
Return val from procedure
ALTER PROCEDURE testme #input VARCHAR(10),
#output VARCHAR(20) output
AS
BEGIN
IF #input >= '1'
BEGIN
SET #output = 'i am back';
RETURN;
END
END
DECLARE #get VARCHAR(20);
EXEC testme
'1',
#get output
SELECT #get
Check this, where the first two parameters are input parameters and the 3rd is an Output parameter in the Procedure definition.
DECLARE #PK_Code INT;
EXEC USP_Validate_Login 'ID', 'PWD', #PK_Code OUTPUT
SELECT #PK_Code
Procedure Example :
Create Procedure [dbo].[test]
#Name varchar(100),
#ID int Output
As
Begin
SELECT #ID = UserID from tbl_UserMaster where Name = #Name
Return;
END
How to call this procedure
Declare #ID int
EXECUTE [dbo].[test] 'Abhishek',#ID OUTPUT
PRINT #ID
From https://learn.microsoft.com/en-US/sql/relational-databases/system-stored-procedures/sp-executesql-transact-sql (originally http://support.microsoft.com/kb/262499)
CREATE PROCEDURE Myproc
#parm varchar(10),
**#parm1OUT varchar(30) OUTPUT**,
**#parm2OUT varchar(30) OUTPUT**
AS
SELECT #parm1OUT='parm 1' + #parm
SELECT #parm2OUT='parm 2' + #parm
GO
DECLARE #SQLString NVARCHAR(500)
DECLARE #ParmDefinition NVARCHAR(500)
DECLARE #parmIN VARCHAR(10)
DECLARE #parmRET1 VARCHAR(30)
DECLARE #parmRET2 VARCHAR(30)
SET #parmIN=' returned'
SET #SQLString=N'EXEC Myproc #parm,
#parm1OUT OUTPUT, #parm2OUT OUTPUT'
SET #ParmDefinition=N'#parm varchar(10),
#parm1OUT varchar(30) OUTPUT,
#parm2OUT varchar(30) OUTPUT'
EXECUTE sp_executesql
#SQLString,
#ParmDefinition,
#parm=#parmIN,
#parm1OUT=#parmRET1 OUTPUT,#parm2OUT=#parmRET2 OUTPUT
SELECT #parmRET1 AS "parameter 1", #parmRET2 AS "parameter 2"
GO
DROP PROCEDURE Myproc
First, declare the output variable:
DECLARE #MyOutputParameter INT;
Then, execute the stored procedure, and you can do it without parameter's names, like this:
EXEC my_stored_procedure 'param1Value', #MyOutputParameter OUTPUT
or with parameter's names:
EXEC my_stored_procedure #param1 = 'param1Value', #myoutput = #MyOutputParameter OUTPUT
And finally, you can see the output result by doing a SELECT:
SELECT #MyOutputParameter
With this query you can execute any stored procedure (with or without an output parameter):
DECLARE #temp varchar(100)
EXEC my_sp
#parameter1 = 1,
#parameter2 = 2,
#parameter3 = #temp output,
#parameter4 = 3,
#parameter5 = 4
PRINT #temp
Here the datatype of #temp should be the same as #parameter3 within your Stored Procedure.
How about this? It's extremely simplified:
The SPROC below has an output parameter of #ParentProductID
We want to select the value of the output of #ParentProductID into #MyParentProductID which is declared below.
Here's the Code:
declare #MyParentProductID int
exec p_CheckSplitProduct #ProductId = 4077, #ParentProductID = #MyParentProductID output
select #MyParentProductID
Try this; it's working fine for the multiple output parameter:
CREATE PROCEDURE [endicia].[credentialLookup]
#accountNumber varchar(20),
#login varchar(20) output,
#password varchar(50) output
AS
BEGIN
SET NOCOUNT ON;
SELECT top 1 #login = [carrierLogin],#password = [carrierPassword]
FROM [carrier_account] where carrierLogin = #accountNumber
order by clientId, id
END
Try for the result:
SELECT *FROM [carrier_account]
DECLARE #login varchar(20),#password varchar(50)
exec [endicia].[credentialLookup] '588251',#login OUTPUT,#password OUTPUT
SELECT 'login'=#login,'password'=#password
CREATE PROCEDURE DBO.MY_STORED_PROCEDURE
(#PARAM1VALUE INT,
#PARAM2VALUE INT,
#OUTPARAM VARCHAR(20) OUT)
AS
BEGIN
SELECT * FROM DBO.PARAMTABLENAME WHERE PARAM1VALUE=#PARAM1VALUE
END
DECLARE #OUTPARAM2 VARCHAR(20)
EXEC DBO.MY_STORED_PROCEDURE 1,#OUTPARAM2 OUT
PRINT #OUTPARAM2
Here is the stored procedure
create procedure sp1
(
#id as int,
#name as nvarchar(20) out
)
as
begin
select #name=name from employee where id=#id
end
And here is the way to execute the procedure
declare #name1 nvarchar(10)
exec sp1 1,#name1 out
print #name1
Please check below example to get output variable value by executing a stored procedure.
DECLARE #return_value int,
#Ouput1 int,
#Ouput2 int,
#Ouput3 int
EXEC #return_value = 'Your Sp Name'
#Param1 = value1,
#Ouput1 = #Ouput1 OUTPUT,
#Ouput2 = #Ouput2 OUTPUT,
#Ouput3 = #Ouput3 OUTPUT
SELECT #Ouput1 as N'#Ouput1',
#Ouput2 as N'#Ouput2',
#Ouput3 as N'#Ouput3'
Here is the definition of the stored_proc:
create proc product(#a int,#b int)
as
return #a * #b
And, this is executing it from Python:
conn = pyodbc.connect('...')
cursor = conn.cursor()
sql = """
SET NOCOUNT ON
declare #r float
exec #r=dbo.product 5,4
select #r
"""
result = cursor.execute(sql)
print (result.fetchall())