I have an interesting scenario where I need to get a dynamic list of parameter values from inside a stored procedure. I want a generic t-sql script that will return this information to me without having to type out each parameter name.
The reason for this is that before executing multiple stored procedures, I must first pass the list of parameter values into another stored procedure call. I don't want the tedious maintenance task that whenever a parameter is added/changed in the SP, I will have to change the nested call as well.
Ex:
create procedure sp1 #a int = 1, #b int = 2
as begin
exec sp2 '1, 2'
....
end
Adding another parameter #c int, should automatically get added on to the string passed in to sp2.
I know I can retrieve the parameter names from sys.parameters using object_id = ##procid. I can concatenate them using for xml path. However, I would need to then use sp_executesql to retreive the values - which would require me to specify each parameter name. Hence, I am no better off than before.
Any tips or help would be greatly appreciated.
Thank you.
Related
I'm creating a stored procedure that uses two multi-value parameters:
#Class AS VARCHAR(5),
#Service AS VARCHAR(5)
(…)
WHERE B.UTRCLS IN (#Class) AND B.UTSVC IN (#Service)
The procedure works fine when both parameters only contain one value. However, when either or both use multiple values, it throws an error.
In report builder the error is the following:
Cannot read the next data row for the dataset DataSet1 (rsErrorReadingNextDataRow)
In SQL Server, the error appears as the following (truncated for length):
Cannot execute the query "SELECT
Col1009,Col1010,Col1008,Expr1003,Expr1004 FROM (SELECT
Col1009,Tbl1001.UTCSNM Col1008,Col1010,SUM(Col1016)
Expr1003,SUM(Col1014) Expr1004 FROM (…)
I don't think I'm doing anything wrong with declaring the parameters. Is this an issue with multi-value parameters in stored procedures?
You need to use a dynamic query:
SET #sqlCommand = 'SELECT * FROM yourTable B WHERE B.UTRCLS IN ( +' #Class + ')' +
' AND B.UTSVC IN (' + #Service +' )'
EXECUTE sp_executesql #sqlCommand
The comments on your post are on the right track. Parameters are single valued for the scope of the stored procedure call, not iterated through for sets of parameter values. I think you have 2 options if you want to pass many values into those parameters.
The first is to expand the character length of your parameters and incorporate a delimiter to segment the values. Your stored procedure code would then need to parse these values and do what is needed from there for each. The STRING_SPLIT() function would help you along the way.
The second options is to define a user data type of type table that mirrors the data structure of the multi-values you need to pass in the parameter. In your stored procedure call you would define a variable of this type, fill it with the values and then pass that variable to your stored procedure. Note that these must be set to READ ONLY when doing so.
Link to MSDN for creating user types: https://learn.microsoft.com/en-us/sql/t-sql/statements/create-type-transact-sql?view=sql-server-2017
I have a stored procedure that requires the table name where some data comes from be dynamic and supplied via a parameter.
However, because you cannot use variables in a lot of SQL statements and I do not want to have to wrap all my statements around exec statements (because it's very clunky, requiring everything to be converted to strings and additional quote marks), is there a way to do this?
So can I create a synonym on the table in my stored procedure, then use that throughout, e.g. this seems to work but I'm not sure of the consequences...
exec('create synonym NEILTABLE FOR '+#var1);
select *
into dbo.temptemp
from NEILTABLE
where location_spatial is null;
drop synonym NEILTABLE;
Thanks.
I have a Stored Procedure, see this picture .
I want to modify Department parameter as nvarchar(30), where it is currently as nvarchar(10).
So how could I achieve this?
Thank you so much
declare #department nvarchar(30)
set #department = CAST (#department_in as nvarchar(30))
If you right click on it, you have the option 'modify' which will generate an alter procedure script for you.
Change the parameter to an nvarchar(30) and run the alter script.
You can't change the type of variable if you already dclared it. In other words:
to change the type of variable, yo need to declare it once again, and as this thread states, you cannot do it.
It is possible to query database objects according to their parameter names, types, length etc using the information schema view
[INFORMATION_SCHEMA].[PARAMETERS]
But you cannot simply update the length on some tables to modify the length, etc of a procedure parameter.
All these objects should be updated using
ALTER PROCEDURE ...
command, at least for stored procedures
You can get the source codes of a procedure by running sp_helptext as follows
sp_helptext yourStoredProcedureName
Then modify the parameter and execute the script as ALTER command
I am trying to pass a multiple value string parameter to a table type parameter in a SQL Server 2012 stored procedure. I paste this code in the dataset of SSRS:
DECLARE #mylist clinic_list_tbltype
INSERT #mylist(n) VALUES (#pm_ChooseClinics)
EXEC sp_Skillset_Summary_With_Callbacks_Report #mylist, #pm_ChooseInterval, #pm_StartDateTime, #pm_EndDateTime
clinic_list_tbltype is a table type I created with one varchar(50) field named "n". I can call this stored procedure from SSMS o.k. like this (and it comes back very fast):
DECLARE #mylist clinic_list_tbltype
INSERT #mylist(n) VALUES ('clinicA'), ('clinicB')
EXEC sp_Skillset_Summary_With_Callbacks_Report #mylist, 'Daily', '6/3/2014', '6/9/2014'
I can run in SSRS for only one clinic (but very slow), but if I try more than one it gives an error saying that
there are fewer columns in the INSERT statement than values specified
in the Values clause
. Even running for one clnic it works, but it takes a very very long time compared to running the query in SSMS. Like 2 minutes vs. 1 second. Must be because I'm passing ('clinicA', 'clinicB') instead of ('clinicA'), ('clinicB').
How to do?
Right I need to give you some back ground 1st.
When you allow SSRS parameter to select multiple values, The selection of multiple values creates a comma deliminated string of value as one string
'value1,value2,value3'
To check values in a string using IN operator we need strings concatenated with commas something like this ....
'value1','value2','value3'
Your Proc
Now in your proc when you insert values explicitly it inserts multiple values into your table.
INSERT INTO Table_Value_Param
VALUES ('value1'), --<-- 1st value/Row
('value2'), --<-- 2nd Value/Row
('value3') --<-- 3rd Value/Row
and this gives you back the expected results as when inside your procedure you execute a statement like
SELECT *
FROM Table_Name
WHERE ColumnName IN (SELECT ColumnName
FROM Table_Value_Param)
On the other hand when you try to insert into table using SSRS report Parameter you table inserts value like
INSERT INTO Table_Value_Param
VALUES ('value1,value2,value3') --<-- One Row/Value containing all the values comma separated
Solution
Creating TVP in this situation doesnt really help, What I do is make use of dbo.Split() function inside my procedure.
You can find many definitions for split function online, for a some cool ones have a look here Split Function equivalent in tsql?
Once you have created this split function just use this function inside your procedure definition you dont even need the Table valued parameters then.
Something like this...
SELECT *
FROM Table_Name
WHERE ColumnName IN (
SELECT Value
FROM dbo.Split(#Report_Param, ',')
)
declare #Vendors_Filter nvarchar(max) = 'a,b,c'
declare #Vendors nvarchar(max)
set #Vendors =''''+replace(#Vendors_Filter,',',''',''')+''''
select #Vendors
In this procedure, I want to delete those number which coming in #msisdn from Master Table and insert into tblDeactive:
ALTER PROCEDURE [dbo].[msisdn_deactivition](#msisdn varchar(1024))
AS
BEGIN
SET NOCOUNT ON;
insert into tblDeactive SELECT * from msisdn_master where msisdn in (#msisdn);
delete from msisdn_master where msisdn in (#msisdn);
END
...but it does not work?
You can't use a single query parameter in place of a list of values. One parameter = one value.
See Parameterize an SQL IN clause for several solutions and lots of discussion about using parameters with the IN( ) predicate.
You need to use a split function, that will split your delimitted #msisdn into a table to select from.
Have a look at this link
How to pass a list of values or array to SQL Server stored procedure?
IN in TSQL needs to take multiple arguments per item. At the moment, if you pass it "123,456,789", it is looking for the single row with value "123,456,789". It isn't looking for "123", "456" or "789".
Look for something like a split udf - plenty on the internet. This takes your delimited string and returns a column of values. Typically you then join the the udf results (rather than use IN).
DON'T use EXEC here, as you shouldn't trust the input.