Option of Sending parameters to stored procedure in SQL Server - sql-server

I have a stored procedure that accepts 10 parameters. I want to send some of these parameters when executing another stored procedure. How can I do that?
Stored procedure definition:
create PROCEDURE [dbo].[SP_name]
#p1 int = null,
#p2 int = null
..
..
#p10 int = null
Execute statement :
exec SP_name valueForP2,vlaueForP5..;
Are there any why to tell exec statement to take just some of the variables?

You can specify the parameter names in the call to the procedure, the other parameters will use the default values.
create PROCEDURE [dbo].[SP_name]
#p1 int = null,
#p2 int = NULL,
#p10 int = NULL
AS
SELECT #p1, #p2, #p10
GO
-- Execute using named parameters
EXEC [SP_name] #p1 = 1, #p10 = 5;

Related

SQL Server stored procedure with default values

I Have SQL Server stored procedure with ~100 parameters, with default values. I have to pass only 3 of them. Is it possible to use StoredProcedureQuery? Now if I have procedure:
create procedure MyProc(#Param1 varchar(30) = "test", #Param2 smallint = 1, #Param3 char = 'a', #Param4 char = 'b',
#Param5 varchar(50) = "test", #Param6 tinyint = 7, #Param7 varchar(3) = "tes", #Param8 varchar(3) = "ADS",
#Param9 varchar(50) = "TEST", #Param10 varchar(8) = "TEST", #Param11 varchar(222) = "TEST")
and executing procedure like this:
StoredProcedureQuery storedProcedureQuery = entityManagerFactory.createEntityManager()
.createStoredProcedureQuery("MyProc");
query.registerStoredProcedureParameter("Param9", String.class, ParameterMode.IN)
.setParameter("Param9", "test9");
query.registerStoredProcedureParameter("Param10", Character.class, ParameterMode.IN)
.setParameter("Param10", "test10");
query.registerStoredProcedureParameter("Param11", String.class, ParameterMode.IN)
.setParameter("Param11", "test11");
Unfortenatly value "test9" goes to #Param1, "test10" goes to #Param2 and "test11" goes to #Param3.
Is it possible to pass parameters by name, not by position?
It is possible to pass parameters by name using JPA and SQL Server using NativeQuery.
Query query = entityManagerFactory.createEntityManager().createNativeQuery("""
DECLARE #return_value int
EXEC #return_value = [dbo].[MyProc]
#Param9 = :Param9,
#Param10 = :Param10,
#Param11 = :Param11
""");
query.setParameter("Param9", "test9");
query.setParameter("Param10", "test10");
query.setParameter("Param11", "test11");

Stored Procedure within a Stored Procedure NVARCHAR output value

I have one stored procedure which return a nvarchar value written like that:
ALTER PROCEDURE [dbo].[GetLastVouchNumber]
#returnVal nvarchar(255) output
AS
BEGIN
SET #returnVal = ( SELECT CONCAT('I',VOUCHNO+1)
FROM TABVOU
WHERE VOUCHER = 'VOUCHER#')
END
I am trying to use the output value from this procedure in another procedure. And this was how I try to write this new procedure:
ALTER PROCEDURE [dbo].[MassAdjInsertIntoYTDTRNI]
#inputPeriod nvarchar(255),
#inputUserId nvarchar(255)
AS
BEGIN
DECLARE #resultOrdNo nvarchar (255)
DECLARE #newOrdNo nvarchar(255)
EXEC #newOrdNo = GetLastVouchNumber #resultOrdNo
INSERT INTO YTDTRNI(TRCDE,PROD,WH,DESCR,UCOST,TCOST,DRAC,CRAC,REM,QTY,UM,ORDNO,TRDATE,SYSDATE,PERIOD,USERID)
SELECT 'AJ',PROD,WH,DESCR,0,-TCOST,STKGL,COSGL,'MASS ADJUSTMENT',0,UM,#newOrdNo, GETDATE(),GETDATE(),#inputPeriod,#inputUserId
FROM INV
I was assuming that this line:
EXEC #newOrdNo = GetLastVouchNumber #resultOrdNo
will store the result of the first procedure into #newOrdNo then after that I can use this #newOrdNo to insert it into another table. But after I execute this second stored procedure, the ORDNO column does not contain any values...
Need advice.
Use OUTPUT keyword when you call GetLastVouchNumber and pass #newOrdNo as an output parameter. Your GetLastVouchNumber procedure returns information with output parameter.
ALTER PROCEDURE [dbo].[MassAdjInsertIntoYTDTRNI]
#inputPeriod nvarchar(255),
#inputUserId nvarchar(255)
AS
BEGIN
DECLARE #resultOrdNo nvarchar (255)
DECLARE #newOrdNo nvarchar(255)
-- Call your stored procedure
EXEC GetLastVouchNumber #newOrdNo OUTPUT
INSERT INTO YTDTRNI(TRCDE,PROD,WH,DESCR,UCOST,TCOST,DRAC,CRAC,REM,QTY,UM,ORDNO,TRDATE,SYSDATE,PERIOD,USERID)
SELECT 'AJ',PROD,WH,DESCR,0,-TCOST,STKGL,COSGL,'MASS ADJUSTMENT',0,UM,#newOrdNo, GETDATE(),GETDATE(),#inputPeriod,#inputUserId
END
You seemed to have confused a return value and an output variable. Your stored proc uses the latter for returning your value, and does not explicitly return anything (Albeit confusing, as you have named your output variable returnVal).
When you call it, you must specify the OUTPUT
EXEC GetLastVouchNumber #resultOrdNo OUTPUT

How to return a variable when Running R from SQL Server

I am trying to run a basic R script from SQL Server through a stored procedure. I am returning a dataset and also want to return/output a variable, but am not able to do that.
Below is the stored procedure I have
DROP PROC IF EXISTS get_iris_dataset;
go
CREATE PROC get_iris_dataset
AS
BEGIN
declare #OutName float
EXEC sp_execute_external_script
#language = N'R'
, #script = N'
iris_data <- iris
out = 5.1;'
, #input_data_1 = N''
, #output_data_1_name = N'iris_data'
,#params= N'#out float OUTPUT'
,#out = #OutName OUTPUT
WITH RESULT SETS (("Sepal.Length" float not null,
"Sepal.Width" float not null,
"Petal.Length" float not null,
"Petal.Width" float not null, "Species" varchar(100)));
END;
return 0
go
I am calling the procedure as below:
declare #OutputVar float
exec #OutputVar = get_iris_dataset
print #OutputVar
It does output the dataset, but I am not able to store the value of the OutputVar.
I am not able to return the value of OutputVar even when I do not output the dataset, and only try to capture the value of OutputVar.
Any help is appreciated.
Thanks in advance!
What I'd do is use the StoredProcedure function (part of the sqlrutils package, which is in turn part of MS R Server 9.0.1) to wrap the R code into a stored procedure. This is slightly different to your original code, since the return values are wrapped in a list. But the idea is still the same.
library(sqlrutils)
testfunc <- function()
{
iris_dataset <- iris
out <- 5.1
list(iris_dataset=iris_dataset, out=out)
}
sp <- StoredProcedure(testfunc, "spTestFunc",
OutputData("iris_dataset"),
OutputParameter("out", "numeric"),
connectionString="<your_connection_string>")
registerStoredProcedure(sp)
Having done that, you can right-click on the proc in SSMS, select "execute Stored Procedure", and SSMS will generate some code for you. The code will look like this:
USE [databasename]
GO
DECLARE #return_value int,
#out_outer float
EXEC #return_value = [dbo].[spTestFunc]
#out_outer = #out_outer OUTPUT
SELECT #out_outer as N'#out_outer'
SELECT 'Return Value' = #return_value
GO
And if you only want the output number, you can simplify the code down to this:
DECLARE #out_outer float
EXEC [dbo].[spTestFunc]
#out_outer = #out_outer OUTPUT
SELECT 'Return Value' = #out_outer
GO

Procedure with update new information

So I have been working on simple procedure for school that asks me to:
(Create a stored procedure called UpdateProduct that takes in a required Product ID parameter and optionally any other one or more fields in the Product table. Then the proc will update any fields passed in but leave any other fields as they were.
If executed like this: UpdateProduct #productID = 1, #name = ‘Steel Ball Bearing’; Only the name should change, all other fields should still contain the value there before the procedure
was called)
This is what I have but still I cant seem to get it to work properly. I am going nuts because I have been trying to figure this out for several days. Any help pointing out my mistake would be awesome.
USE AdventureWorks2012
GO
CREATE PROC UpdateProduct2
#ProductID INT ,
#Name nvarchar (50)= ISNULL,
#ProductNumber nvarchar (25) =ISNULL,
#Color nvarchar (15)=ISNULL
AS
BEGIN
UPDATE [Production].[Product]
SET
Name = ISNULL (#Name,Name),
ProductNumber = ISNULL (#ProductNumber,ProductNumber),
Color = ISNULL (#Color, Color)
WHERE #Name=Name
END
I think your where clause should be:
WHERE ProductID = #ProductID;
rather than
WHERE #Name=Name
Also you need to use NULL rather than ISNULL to set the parameter defaults:
CREATE PROC UpdateProduct2
#ProductID int,
#Name nvarchar(50) = NULL,
#ProductNumber nvarchar(25) = NULL,
#Color nvarchar(15) = NULL
AS
BEGIN
UPDATE [Production].[Product]
SET Name = ISNULL (#Name,Name),
ProductNumber = ISNULL (#ProductNumber,ProductNumber),
Color = ISNULL (#Color, Color)
WHERE ProductID = #ProductID;
END
EDIT
To answer the question about specifying NULL as the default, yes there is a reason, it allows you to call the procedure without passing the parameter.
Take the following two procedures:
CREATE PROCEDURE dbo.P1 #p1 VARCHAR(20), #p2 VARCHAR(20)
AS
BEGIN
SELECT P1 = #p1, P2 = #p2;
END;
GO
CREATE PROCEDURE dbo.P2 #p1 VARCHAR(20) = NULL, #p2 VARCHAR(20) = NULL
AS
BEGIN
SELECT P1 = #p1, P2 = #p2;
END;
The first using no default, and the latter with NULL as the default. The only way to call the first procedure is to send all parameters, e.g.
EXECUTE dbo.p1;
EXECUTE dbo.p1 #P2 = 'TEST';
EXECUTE dbo.p1 #P1 = 'TEST';
Will generate the following errors:
Msg 201, Level 16, State 4, Procedure P1, Line 0
Procedure or function 'P1' expects parameter '#p1', which was not supplied.
Msg 201, Level 16, State 4, Procedure P1, Line 0
Procedure or function 'P1' expects parameter '#p1', which was not supplied.
Msg 201, Level 16, State 4, Procedure P1, Line 0
Procedure or function 'P1' expects parameter '#p2', which was not supplied.
Whereas this:
EXECUTE dbo.p2;
EXECUTE dbo.p2 #P2 = 'TEST';
EXECUTE dbo.p2 #P1 = 'TEST';
Will generate:
P1 P2
NULL NULL
P1 P2
NULL TEST
P1 P2
TEST NULL

How to pass a variable number of parameters to a SQL Server stored procedure?

I used SQL Server 2005 for my small web application. I Want pass parameters to SP .
But there is one condition. number of parameter that can be change time to time.
Think ,this time i pass name and Address , next time i pass name,surname,address ,
this parameter range may be 1-30 ,
You declare the procedure with default parameters and you invoke it with named parameters instead of positional parameters:
CREATE PROCEDURE usp_myProcedure
#name varchar(100) = '',
#surname varchar(100) = '',
#address varchar(100) = ''
AS
BEGIN
...
END
to invoke it from T-SQL:
exec usp_myProcedure #name='John', #surname = 'Doe';
exec usp_myProcedure #name='Jane', #address = '123 Anystreet';
To invoke it from C#:
SqlCommand cmd = new SqlCommand('usp_MyProcedure', ...);
cmd.CommandType = commandtype.StoredProcedure;
cmd.Parameters.AddWithValue('#name', 'John');
cmd.Parameters.AddWithValue('#surname', 'Doe');
You can use XML types. Here is a sample procedure:
CREATE PROCEDURE udsp_VariableParams(#params XML)
AS
BEGIN
DECLARE #vdoc INT
EXEC sp_xml_preparedocument #vdoc OUTPUT, #params
SELECT * FROM OPENXML(#vdoc, '/params/param', 1) WITH ([paramname] VARCHAR(40), [paramvalue] VARCHAR(150))
EXEC sp_xml_removedocument #vdoc
END
EXEC udsp_VariableParams
'<params>
<param paramname="name" paramvalue="value"/>
<param paramname="address" paramvalue="value"/>
</params>'
EXEC udsp_VariableParams
'<params>
<param paramname="name" paramvalue="value"/>
<param paramname="surname" paramvalue="value"/>
<param paramname="address" paramvalue="value"/>
</params>'
You can set the default values for the parameters at the SP level so that the parameters become optional.
e.g.
CREATE PROCEDURE dbo.Test
#param1 int, -- Not an optional
#param2 int = 10, --Optional
#param3 bit = 0, --Optional
#param4 varchar(50) = '', --Optional
#param5 nvarchar(100) = null --Optional
-- more parameters .....
AS
BEGIN
-- The SQL goes here...
END
Then you can populate the optional parameters at your choice.
Preparing and exctracting tags from XML is aperformance killer. The inconsistant execution timings depends on whether plan is cached or not.
Using NVARCHAR(MAX) instead is a better option. Just prepare you parameter strings with "#name=Value" pair, and add a unique parameter sepearetor if needed. Inside the procedure use SUBSTRING, CHARINDEX, etc. to get individual parameters.

Resources