Passing multiple value parameters in SSRS to stored procedure - sql-server

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

Related

Giving single parameter having commas to SQL stored procedure

I am using visual FoxPro and SQL. I am creating reports in visual Foxpro using SQL data. All connections are set.
here is one store procedure and I want to give parameter like
#A=''AA','BB','CC''
but because of comma it acts like separate parameters to procedure
that is used for IN operator
eg. where V_TYPE in (#A)
Parameter value come from Visual FoxPro.''AA','BB','CC'' by the VFP program.
this is single parameter for Stored procedure.
eg. EXEC testProc ''AA','BB','CC'' .
but because of comma its act like three para .
Is there problem with quotes ??seeting of quoted identifier
please tell me how should I give parameter like this.
thanks in Advance!
Unfortunately you have been given advices that you shouldn't use at all and wide open to SQL injection attacks. Instead there are multiple safe ways to do that.
One of them is to create a temp table in SQL server, insert values there and use inner join instead of an IN query.
One another way is to use a procedure to parse comma separated values to a table server side and use it in a join.
Yet another way is to pass an XML data string, create table at server side and do a join. Below is a sample using XML (for the other 2 samples look here - samples):
LOCAL lnHandle, cXML, myInQuery
TEXT TO myInQuery noshow
DECLARE #hDoc int
exec sp_xml_preparedocument #hDoc OUTPUT, ?m.cXML
SELECT * FROM [Northwind]..[Products]
WHERE ProductID IN
(
SELECT myID FROM OPENXML(#hDoc, ?m.cNodename, 1) WITH (myid int)
)
EXEC sp_xml_removedocument #hDoc
ENDTEXT
** Local cursor
CREATE CURSOR test (myID i)
INSERT INTO test VALUES (1)
INSERT INTO test VALUES (3)
INSERT INTO test VALUES (5)
** Local cursor
CURSORTOXML('test','cXML',2)
cNodeName = '/VFPData/test' && CursorToXML by default use VFPData as root, and tablename in lowercase for rows
lnHandle = SQLSTRINGCONNECT('Driver={SQL Native Client};server=.\SQLExpress;Trusted_Connection=yes')
SQLEXEC(m.lnHandle, m.myInQuery, 'result')
SQLDISCONNECT(m.lnHandle)
SELECT result
BROWSE
Note: With these types of approaches your values could be any type without the worry of having quotes or other characters in it (int, char, datetime ...).

Pass test data to table-valued parameter within SQL

Is it possible, and if so how, to pass data to a table-valued parameter of a stored function using SQL EXEC?
I know how to pass in data from C#. One of my four stored procs using table-valued parameters is not producing the expected results. I'd like to execute my proc from SQL server management studio for debugging purposes, but I am unable to find the correct syntax for doing so, if such a syntax even exists. I haven't found anything relevant in the docs.
My type table:
CREATE TYPE [MyNameSpace].[MyTypeTable] AS TABLE(
//... all my fields
)
My stored proc:
//... bunch of stuff
ALTER PROCEDURE [MyNameSpace].[MyStoredProc]
#MyTypeTableVar MyTypeTable READONLY
AS
BEGIN
//Do a bunch of stuff
//Want to test the stuff in here
END
I have tried:
IF OBJECT_ID('tempdb.dbo.#MyTempTable') IS NOT NULL DROP TABLE tempdb.dbo.#MyTempTable;
select top 0 *
into #MyTempTable
//existing table with structure that matches the table-valued param
from MyNameSpace.MyTable;
//...Long insert statement assigning test data to #MyTempTable
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #MyTempTable;
which throws:
Operand type clash: nvarchar is incompatible with MyTypeTable
You can't use a temp table - you have to use a table variable:
declare #t [MyNameSpace].[MyTypeTable]
insert into #t (/*columns*/) values
(/* first row */),
(/* second row */)
EXECUTE MyNameSpace.MyStoredProc #MyTypeTableVar = #t;
(You can populate it with either INSERT ... VALUES as shown above or INSERT ... SELECT if you have an existing table containing the data you care about)
Here's a working example:
-- Declare a table parameter
DECLARE #registryUpdates AS typ_KeyValuePairStringTable;
-- Insert one row
INSERT INTO #registryUpdates
VALUES ('Hello', 'World');
-- Call Stored Procedure
EXEC prc_UpdateRegistry #registryUpdates

SSRS Records Not Showing Up When (Select All) Is Used But Is When Selecting A Particular Value

I have a report that is has a multiple value parameter. It has available values (1, 2, 3, 4, 5, and blank). The blank value isn't NULL it is just an empty cell.
For testing purposes, there should only be one record showing up. The record has a blank value in the cell that I am using to filter on in my stored procedure.
In the parameter drop down, I see all of the options. If I choose the (Select All) option, I don't get the record I am wanting. However, if I choose just the blank value, I get the record I am wanting. I updated the record manually to "2". I choose (Select All) and I get the record. I choose only the "2" value and I get the record. If I remove the value again to make the value blank, I only get the record if I only choose the "Blank" option in the drop down.
I make a text box to output the value of the parameter and it is showing blank when it is selected either by itself or with other values.
What am I missing in either my stored procedure or in my report? Thanks in advance.
When you have a multiple select parameter, SSRS should send a comma separated list of values to your stored procedure. You are responsible for splitting these back out into something that you can join on.
In the report itself, you don't get the list of values in a nicely wrapped up string for displaying. I've had to use code to iterate over the values in the parameter.
I tested what SSRS is doing when you have a blank available value. I created a test report that had the six available options and then a stored procedure to force the selected values to be output:
CREATE PROCEDURE dbo.Test_RPT
(
#TestMultiSelect varchar(1000)
)
AS
SELECT #TestMultiSelect RVAL
In the report, I just had a single textbox that displayed this RVAL field.
If I put the blank option at the start, the output was 1,2,3,4,5. If the blank option was at any other location, it was included: 1,2,3,,4,5, 1,2,3,4,5,.
If you want to pass multiple values to Sql IN clause within a Stored Procedure from SSRS report dataset, slight changes needed in the Stored Procedure:
See the Sample WHERE clause in a SP
...
AND Courses.Type_Code IN (#Type_Code)
Add a SplitString() function to split the passed parameters based on a delimiter.
The body of the SplitString() will look like:
CREATE FUNCTION [dbo].[SplitString]
(
#pString VARCHAR(8000),
#pDelimiter CHAR(1)
)
RETURNS #Values TABLE (Value VARCHAR(50))
AS
BEGIN
DECLARE #xml as XML;
SET #xml = cast(('<X>'+replace(#pString, #pDelimiter, '</X><X>')+'</X>') as xml);
INSERT #Values
SELECT N.value('.', 'varchar(50)') as value
FROM #xml.nodes('X') as T(N);
RETURN
END;
Finally the IN clause will looks like:
...
AND Courses.Type_Code IN (SELECT * FROM dbo.SplitString(#type_code,','))

T-SQL: pass an array of ids to a stored procedures

I'm trying to send and array of parameters to a stored procedure
SELECT [id_Curso] AS IDCurso
,[Cod_Estabelecimento] AS CodEstabelecimento
,[Des_Estabelecimento] AS DesEstabelecimento
,[Cod_Curso] AS CodCurso
,[Des_Curso] AS DescCurso
,[Cod_Grau] AS CodGrau
,[Des_Grau] AS DescGrau
,[Cod_Area_Educacao] AS CodAreaEducacao
FROM [BEP_DEV].[dbo].[Curso]
where [Cod_Area_Educacao] in #List
DECLARE #List VARCHAR(MAX);
SELECT #List = '(1,2,3,4)';
SELECT [id_Curso] AS IDCurso
,[Cod_Estabelecimento] AS CodEstabelecimento
,[Des_Estabelecimento] AS DesEstabelecimento
,[Cod_Curso] AS CodCurso
,[Des_Curso] AS DescCurso
,[Cod_Grau] AS CodGrau
,[Des_Grau] AS DescGrau
,[Cod_Area_Educacao] AS CodAreaEducacao
FROM [BEP_DEV].[dbo].[Curso]
where [Cod_Area_Educacao] in (1,2,3,4)
How can I transform the first case in something like the 2nd one (which works.)?
I tried also with xml but also can't make it work.
Any help?
There are a number of possibilities for that, but given the you're on SQL 2008 the number one choice would be to use the new table valued parameters, in which you can send a whole table to a query or stored procedure in a single go (in your case, a table with a single column with an arbitrary number of IDs).
First create a table type in your database:
CREATE TYPE idTable AS TABLE (id INT)
Then just declare your procedure with a parameter of that type, and use it like any other table:
CREATE PROCEDURE SelectList (#IDs idTable READONLY) AS
SELECT * FROM sometable
INNER JOIN #IDs AS idTable ON idTable.id=sometable.id
There is a great article that discusses this and other methods in detail for doing what you need http://www.sommarskog.se/arrays-in-sql.html
You can use a udf that parses the string and inserts the values into a table (containing one int column in your case), and then join your Curso table on the table resulting from calling the udf on your CSV string.
I would pass it as xml. Its easy and very performant. Here is a good post with the details. https://www.simple-talk.com/blogs/2012/01/05/using-xml-to-pass-lists-as-parameters-in-sql-server/

Help me with My Stored Procedure

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.

Resources