Why does this script return a pair of nulls? I'm using SQL Server 2008, script run in MSSMS.
CREATE PROCEDURE proc_Test
(
#Input int,
#Out1 int OUTPUT,
#Out2 varchar(10) OUTPUT
)
AS
BEGIN
SET NOCOUNT OFF
SET #Out1 = 100 + #Input
SET #Out2 = 'result=' + CONVERT(varchar,#Out1)
RETURN
END
GO
DECLARE #Out1 int, #Out2 varchar(10)
exec proc_Test #Input=1, #Out1=#Out1, #Out2=#Out2
select #Out1, #Out2
You need to specify vars as output:
DECLARE #Out1 int, #Out2 varchar(10)
exec proc_Test #Input = 1, #Out1 = #Out1 output, #Out2 = #Out2 output
select #Out1, #Out2
As a small matter of style try not to name the vars that receive the results the same as the parameter variables; it gets too confusing.
Related
I use the following code to check if one file exists in a folder and it works with returning 1.
Code A:
DECLARE #result INT
EXEC master.dbo.xp_fileexist 'C:\Users\folder\123.json', #result OUTPUT
SELECT #result
Now I want to a variable to represent the path and create the following code, but it does not work, returning error message saying
Msg 22027, Level 15, State 1, Line 2
Usage: EXECUTE xp_fileexist [, OUTPUT]
Code B:
DECLARE #rootfolder AS NVARCHAR(MAX),
#file AS NVARCHAR(MAX)
declare #jsonfilename varchar(100)
set #rootfolder = 'C:\Users\folder\'
set #jsonfilename = '123.json'
set #file = concat(#rootfolder, #jsonfilename);
DECLARE #result INT
EXEC master.dbo.xp_fileexist #file, #result OUTPUT
select #result
If I print #file, it's exactly the same as what I want. Not sure what is the problem and how to fix it.
Looks like xp_fileexist does not accept VARCHAR(MAX) or NVARCHAR(MAX) as input. I get the same error as you (SQL Server 2017 Ent.) but specifying the character length works:
DECLARE #rootfolder AS VARCHAR(max),
#file AS NVARCHAR(255)
declare #jsonfilename varchar(100)
set #rootfolder = 'C:\Users\folder\'
set #jsonfilename = '123.json'
set #file = concat(#rootfolder, #jsonfilename);
DECLARE #result INT
EXEC master.dbo.xp_fileexist #file, #result OUTPUT
select #result
Starting in SQL Server 2017 there is also a new DMF sys.dm_os_file_exists() that does the same thing and does support MAX:
DECLARE #rootfolder AS VARCHAR(max),
#file AS NVARCHAR(max)
declare #jsonfilename varchar(100)
set #rootfolder = 'C:\Users\folder\'
set #jsonfilename = '123.json'
set #file = concat(#rootfolder, #jsonfilename);
DECLARE #result INT
SELECT #result = file_exists FROM sys.dm_os_file_exists(#file)
I have written a stored procedure with the following format:
ALTER PROCEDURE usp_data_migration
(#sourceDatabase varchar(50),
#sourceTable varchar(50),
#targetDatabase varchar(50),
#targetTable varchar(50),
#finaloutput varchar(max) output)
AS
BEGIN
----Set of SQL Blocks
END
Then, I am executing the procedure:
DECLARE #finaloutput1 varchar(300)
EXEC usp_data_migration 'Yousuf', 'emp', '[City Branch]', 'emp_tgt', #finaloutput1 output
SELECT #finaloutput1
By executing this way I don't proper output.
When I execute this way:
DECLARE #finaloutput1 varchar(300)
EXEC usp_data_migration #sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt',
#finaloutput1 output
SELECT #finaloutput1
I get an error message saying:
Msg 119, Level 15, State 1, Line 41
Must pass parameter number 5 and subsequent parameters as '#name = value'. After the form '#name = value' has been used, all subsequent parameters must be passed in the form '#name = value'.
And if I removed my output parameter and execute the procedure, I get my desired output but I am not able to get my result as an output.
EXEC usp_data_migration #sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt'
What should I do?
Thanks in advance.
The error message is self-explanatory - you should name all of your parameters.
DECLARE #finaloutput1 varchar(300);
EXEC dbo.usp_data_migration -- always use schema prefix
#sourceDatabase = 'Yousuf',
#sourceTable = 'emp',
#targetDatabase = '[City Branch]',
#targetTable = 'emp_tgt',
#finaloutput = #finaloutput1 OUTPUT;
SELECT #finaloutput1;
You have to Select like this
Example 1
create procedure p1
(
#id INT,
#name varchar(20) OUTPUT,
#company varchar(20) OUTPUT
)
AS
BEGIN
Set #name = 'name'
Set #company = 'company'
select #name , #company from table1 where id = #id;
END
GO
Example 2
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
Please refer more here
Simple Example:
create procedure proc2 #var int out,#var2 varchar(10) out
as
begin
set #var=(select max(id) from customer);
set #var2=(select name from customer where id=#var);
end
declare #maxid int;
declare #maxname varchar(10);
exec proc2 #maxid out,#maxname out;
select #maxid,#maxname;
I need to pass set of int to sql procedure.
alter PROC PrCustomerServicesUpd(
#CustomerId UNIQUEIDENTIFIER,
#ServicesIdXml NVARCHAR(1000),
#ServicesIdCount INT =1
)
AS
DECLARE #XmlDocHanle INT
EXEC sp_Xml_PrepareDocument #XmlDocHanle OUTPUT, #ServicesIdXml
SELECT * FROM OPENXML(#XmlDocHanle, '/ROOT/Services/ServicesId',#ServicesIdCount)
WITH (ServiceId INT)
EXEC sp_Xml_RemoveDocument #XmlDocHanle
go
PrCustomerServicesUpd '443c293e-fc78-4562-97f8-ee1f2b54f813'
,'<Services><ServiceId>12</ServiceId><ServiceId>156</ServiceId></Services>',22
This script returns one empty field named 'ServiceId' instead of 2 rows.
Assuming this is SQL Server 2000 (otherwise there is no sane reason to use OPENXML), you need to get the text() within the node, otherwise it tries to find the attribute "ServiceId" within the node "ServiceId". Also your parameter XML is completely out of sync with what the proc expects.
alter PROC PrCustomerServicesUpd(
#CustomerId UNIQUEIDENTIFIER,
#ServicesIdXml NVARCHAR(1000),
#ServicesIdCount INT =1
)
AS
DECLARE #XmlDocHanle INT
EXEC sp_Xml_PrepareDocument #XmlDocHanle OUTPUT, #ServicesIdXml
SELECT * FROM OPENXML(#XmlDocHanle, '/ROOT/Services/ServicesId',#ServicesIdCount)
WITH (ServiceId INT 'text()')
EXEC sp_Xml_RemoveDocument #XmlDocHanle
GO
PrCustomerServicesUpd '443c293e-fc78-4562-97f8-ee1f2b54f813'
,'<ROOT><Services><ServicesId>12</ServicesId><ServicesId>156</ServicesId></Services></ROOT>',3
Using the XML data type
alter PROC PrCustomerServicesUpd
#CustomerId UNIQUEIDENTIFIER,
#ServicesIdXml xml,
#ServicesIdCount INT =1
AS
select service.id.value('.','int')
from #ServicesIdXml.nodes('/ROOT/Services/ServicesId') service(id)
GO
You can pass set of int in varchar(1000) with comma separator
so int value passing as "1223,12,254,5545,8787,8787,787,78,45475,45,45"
And in store procedure you can get one by one id with fnSplit function (Tabular).
ALTER function [dbo].[fnSplit](
#String nvarchar (4000),
#Delimiter nvarchar (10)
)
returns #ValueTable table ([Value] nvarchar(4000))
begin
declare #NextString nvarchar(4000)
declare #Pos int
declare #NextPos int
declare #CommaCheck nvarchar(1)
--Initialize
set #NextString = ''
set #CommaCheck = right(#String,1)
--Check for trailing Comma, if not exists, INSERT
--if (#CommaCheck <> #Delimiter )
set #String = #String + #Delimiter
--Get position of first Comma
set #Pos = charindex(#Delimiter,#String)
set #NextPos = 1
--Loop while there is still a comma in the String of levels
while (#pos <> 0)
begin
set #NextString = substring(#String,1,#Pos - 1)
insert into #ValueTable ( [Value]) Values (#NextString)
set #String = substring(#String,#pos +1,len(#String))
set #NextPos = #Pos
set #pos = charindex(#Delimiter,#String)
end
return
end
so you can get the one by one value as
"Select value from dbo.fnsplit (#values,',')"
I think you mean ServiceId and not ServicesId.
In addition the third parameter of OPENXML should not be #ServicesIdCount, it should be a value describing what sort of output you want.
Don't think you specify a ROOT node in your XML, so remove that
SELECT * FROM OPENXML(#XmlDocHanle, '/ROOT/Services/ServicesId',#ServicesIdCount)
WITH (ServiceId INT)
should be
SELECT * FROM OPENXML(#XmlDocHanle, '/Services/ServiceId', 1)
WITH (ServiceId INT)
I'm trying to combine a result mixed with some SELECTs.
I wanted to set #result combined with the result of [proc_Get_Frame_CourseNum] procedure but It didn't work.
declare #str varchar(300)
declare #result varchar(200)
declare #temp varchar(20)
declare #i int
set #str='110,120,130,140'
set #result=''
set #temp=''
set #i=0
while #i<len(#str)/4+1
begin
set #temp=substring(#str,1,3)
set #str=substring(#str,2,len(#str))
set #result=#result+ exec [proc_Get_Frame_CourseNum] #temp
set #i=#i+1
end
select #temp
Personally, I'd make use of output variables
CREATE PROCEDURE proc_Get_Frame_CourseNum
#temp varchar(20),
#outValue varchar(50) OUTPUT
AS
BEGIN
--do stuff
--before you leave the method or do your final SELECT
SET #outValue = 'whatever your result is'
--more stuff
END
Then in your code, you just go:
DECLARE #outValue VARCHAR(20)
-- rest of your code
EXEC [proc_Get_Frame_CourseNum] #temp, #outValue OUT
SET #result = #result + #outValue
Alternatively, you could just dump the results of the SP into a temp table, then read from it into your #Result variable.
You can't interpolate the result of one procedure by appending it.
I am assuming now that [proc_Get_Frame_CourseNum] returns a scalar result.
So run exec [proc_Get_Frame_CourseNum] #temp in another line of batch (before set #result = #result + call)
Your query should look like,
declare #scalarResult = exec [proc_Get_Frame_CourseNum] #temp
set #result=#result+ #scalarResult
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())