Passing Multi Value Paramter in stored proc - stored-procedures

Firstname emp_Fullname
--------------------------------------
chetan Patel, Chetan
mike Shah, Mike
ronie Desai, Ronie
create proc stored_procedure
#firstnamer varchar(max)
#fullname varchar(max)
as
begin
select ......
from....
where Firstname in (SELECT Value FROM dbo.FnSplit(#firstname,','))
--and emp_Fullname in (SELECT Value FROM dbo.FnSplit(#fullname,','))
I want result for below statement
exec stored_procedure 'chetan,ronie', 'Patel, Chetan,Shah, Mike'
How can I pass more than 2 emp_fullname in parameter in given stored procedure? Below is my function dbo.FnSplit that worked for multi value Firstname parameter but not working multi value fullname parameter.
ALTER FUNCTION [dbo].[FnSplit]
(
#List nvarchar(2000),
#SplitOn nvarchar(5)
)
RETURNS #RtnValue table (Id int identity(1,1), Value nvarchar(100))
AS
BEGIN
WHILE(Charindex(#SplitOn, #List) > 0)
BEGIN
INSERT INTO #RtnValue (value)
SELECT
VALUE = ltrim(rtrim(Substring(#List, 1, Charindex(#SplitOn, #List) - 1)))
SET #List = SUBSTRING(#List, Charindex(#SplitOn, #List) + len(#SplitOn), len(#List))
END
INSERT INTO #RtnValue (Value)
SELECT
VALUE = ltrim(rtrim(#List))
RETURN
END

Firstname in (SELECT Value FROM dbo.FnSplit(#firstname,'|'))
and emp_Fullname in (SELECT Value FROM dbo.FnSplit(#fullname,'|'))
and I figured that still in SSRS double click on dataset click parmater instead of default value choose expression and set it to "join(#firstname.value,"|")" and samething for other "join(#fullname.value,"|")" and now run it. Multi valye parameter should work find by doing above procedure.
Thanks to my self lol:) it took me 3 days to figured, thought you guys can use it!

Related

why does Stored procedure not return the 'Out' parameter in bigquery?

I am writing below Stored Procedure in BigQuery but not sure where did I do wrong.
The 'Out' Parameter does not return anything.
Stored Procedure:
create procedure if not exists test.GetNumTherapistSessions(
in LastNamee string,
out NumSessione int64
)
begin
select count(s.SessionNum) as NumSession from test.Session s
inner join test.Therapist t on s.TherapistID=t.TherapistID
where t.LastName=LastNamee;
end
and Here is how I declare the output parameter and how to call it:
declare NumSession int64;
call test.GetNumTherapistSessions("Risk",NumSession);
Here is the output:
So far everything seems right, but when I select the NumSession, it returns Null:
select NumSession;
Output:
Try SET NumSessione = (select count...);
create procedure if not exists test.GetNumTherapistSessions(
in LastNamee string,
out NumSessione int64
)
begin
SET NumSessione = (
select count(s.SessionNum) as NumSession from test.Session s
inner join test.Therapist t on s.TherapistID=t.TherapistID
where t.LastName=LastNamee
);
end
As shown in this docs of bigquery Link you can use SET to assign any values you need to a specific Variables.
Note that bigquery don't have SELECT INTO statement inside procedure.
Examples:
SET (value1, value2, value3) = (SELECT AS STRUCT c1, c2, c3 FROM table_name WHERE condition)
From this answer:select-into-with-bigquery
Another Example:
UPDATE dataset.Inventory
SET quantity = quantity +
(SELECT quantity FROM dataset.NewArrivals
WHERE Inventory.product = NewArrivals.product),
supply_constrained = false
WHERE product IN (SELECT product FROM dataset.NewArrivals)
Another examples can be found here: Link

Using a Cursor in a Stored Procudure

I have the following code extremely slow code in a MS SQL 2016 Stored Procedure (I think it is stuck in a never ending loop):
#DBID Integer
AS
BEGIN
DECLARE TagCursor CURSOR FOR SELECT MemberID
FROM ADMIN_API_Master_Members_List
WHERE DBID= #DBID AND Len(Pending) > 0
DECLARE #ProgramCode VARCHAR(10)
DECLARE #Values VARCHAR(MAX)
DECLARE #tag nvarchar(10)
OPEN TagCursor
FETCH NEXT FROM TagCursor INTO #tag
WHILE (##FETCH_STATUS = 0)
BEGIN
SELECT #ProgramCode = Program_Code, #Values= Pending FROM ADMIN_API_Master_Members_List WHERE MemberID= #tag
DELETE FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE
WHERE (MemberID =#tag)
INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE ( ProgramCode, MemberID, DBID, PMID)
SELECT #ProgramCode, #tag, #DBID , Value FROM STRING_SPLIT(#Values, ',')
END
CLOSE TagCursor
DEALLOCATE TagCursor
END
This Procedure is only a maintenance process and does not get run very often but when it does it would be nice to only take a few seconds. The purpose is to normalize in a Table one record for each comma seperated value in the ADMIN_API_Master_Members_List Table and put it into the ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE with the Program_Code and MemberID and DBID.
There are only about 150 records in the Master Table and the comma separated strings may have 5 values. I am receptive to other solutions.
Thanks in advance
I haven't tested this, but like I mentioned in the comments, using a CURSOR is a bad idea; they are inherently slow as SQL Server excels at set based methods not iterative tasks (and a CURSOR is the latter).
I suspect that this achieves the answer you're after and avoids the CURSOR all together:
CREATE PROC YourProc #DBID integer
AS
BEGIN
DECLARE #Deleted table (ProgramCode varchar(10),
[Value] varchar(MAX),
Tag nvarchar(10));
DELETE HT
OUTPUT deleted.Program_Code,
deleted.Pending,
deleted.MemberID
INTO #Deleted (ProgramCode,
[Value],
Tag)
FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE AS HT
JOIN ADMIN_API_Master_Members_List AS MML ON HT.MemberID = MML.MemberID
WHERE MML.[DBID] = #DBID
--AND LEN(Pending) > 0; --Changed this to below to be SARGable, as only a string with the value '' will have a length of 0.
AND Pending != '';
INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE (ProgramCode,
MemberID,
DBID,
PMID)
SELECT D.ProgramCode,
D.Tag,
#DBID,
SS.Value
FROM #Deleted AS D
CROSS APPLY STRING_SPLIT(D.[Value], ',') AS SS;
END;
The reason for the infinite loop may be that you have no "Fetch next" inside your loop
Try the below:
#DBID Integer
AS
BEGIN
DECLARE TagCursor CURSOR FOR SELECT MemberID
FROM ADMIN_API_Master_Members_List
WHERE DBID= #DBID AND Len(Pending) > 0
DECLARE #ProgramCode VARCHAR(10)
DECLARE #Values VARCHAR(MAX)
DECLARE #tag nvarchar(10)
OPEN TagCursor
FETCH NEXT FROM TagCursor INTO #tag
WHILE (##FETCH_STATUS = 0)
BEGIN
SELECT #ProgramCode = Program_Code, #Values= Pending FROM ADMIN_API_Master_Members_List WHERE MemberID= #tag
DELETE FROM ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE
WHERE (MemberID =#tag)
INSERT INTO ADMIN_API_PMID_PROGRAM_CODE_HOLDING_TABLE ( ProgramCode, MemberID, DBID, PMID)
SELECT #ProgramCode, #tag, #DBID , Value FROM STRING_SPLIT(#Values, ',')
FETCH NEXT FROM TagCursor INTO #tag
END
CLOSE TagCursor
DEALLOCATE TagCursor
END

Return a result set as output param in a sybase stored proc

I have a stored procedure, in which I want to simply store result of a select statement in an output parameter and return that , how can i do that.
I would appreciate if you give me the right syntax of it, since i am new to DB and Sybase specially, that's why i am just giving u a pseudo code for that..
/pseudo code
create my_proc(in_param i,out_param o1,out_param o2){
.....other select and insert statements
.....
if(xyz=true){
o1 = select * from emplyees
}
return o1,o2
}
You don't need output parameters to return result of query, try below code
create procedure proc1
(
#val1 integer
)
as
begin
select * from emplyees
end
/pseudo code
create my_proc(in_param int,out_param1 int out,out_param2 int out)
BEGIN
.....other select and insert statements
if(xyz=true)BEGIN
select out_param1=e.col1,out_param1=2=e.col2 from emplyees e
END
END
Modify datatypes accordingly
Thanks,
Gopal

passing array as parameters, stored procedures don't update result

I have an int[] and pass it as parameter to a procedure, when the method is called, no error is reported but nothing is updated in the database. There may be something wrong in my Add() since the Stored Procedure is written by another programmer. I cannot modify this stored procedure so everything must be solved in the Add().
FYI, the Add() takes an array of userIDs and a groupID as parameters, format them and run the stored procedure. The stored procedure inserts userIDs and groupID into the DB
For example:
if userIDs=[1,2,3] and groupID=4,
then I want the following data to be inserted into the DB
userID groupID
1 4
2 4
3 4
The stored procedure
USE [xyz]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spSaveSomething]
#groupID INT,
#userIDs TEXT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #handle INT
EXEC sp_xml_preparedocument #handle OUTPUT, #userIDs
DELETE FROM tbl1 WHERE i_GroupID = #groupID AND i_NetworkUserID IN (SELECT [ID] FROM OPENXML (#handle, 'ROOT/VAL', 1) WITH ([ID] INT))
INSERT INTO tbl1 (i_NetworkUserID, i_GroupID)
SELECT [ID], #groupID FROM OPENXML (#handle, 'ROOT/VAL', 1) WITH ([ID] INT)
EXEC sp_xml_removedocument #handle
END
The Add()
public void AddUsers(int[] UserIDs, int GroupID)
{
List<int> testList = new List<int>();
foreach (int id in UserIDs)
{
testList.Add(id);
}
XmlSerializer xs = new XmlSerializer(typeof(List<int>));
MemoryStream ms = new MemoryStream();
xs.Serialize(ms, testList);
string resultXML = UTF8Encoding.UTF8.GetString(ms.ToArray());
SqlParameter param1 = new SqlParameter("#userIDs", resultXML);
SqlParameter param2 = new SqlParameter("#groupID", GroupID);
context.Database.ExecuteSqlCommand("spSaveSomething #groupID, #userIDs",
param2, param1);
}
Convert the int[] into a string with Comma seprated and then in Stored Prodedure, us in ie
WHERE i_NetworkUserID in #UserIds
for me, your approach a little bit complicated.
I suggest to rewrite your procedure like
alter procedure [dbo].[spSaveSomething]
(
#groupID int,
#userIDs nvarchar(max)
)
as
begin
set nocount on
declare #tmp_Users table (ID int primary key)
insert into #tmp_Users
select T.C.value('.', 'int')
from #userIDs.nodes('List/ID') as T(C)
delete from tbl1
where
i_GroupID = #group_ID and
i_NetworkUserID in (select ID from #tmp_Users)
insert into tbl1 (i_NetworkUserID, i_GroupID)
select ID, #groupID
from #tmp_Users
-- actually it's strange - you deleting users and then inserting
-- may be you wanted to do this:
-- delete from tbl1
-- where
-- i_GroupID = #group_ID and
-- i_NetworkUserID not in (select ID from #tmp_Users)
-- insert into tbl1 (i_NetworkUserID, i_GroupID)
-- select U.ID, #groupID
-- from #tmp_Users as U
-- where
-- not exists (
-- select T.*
-- from tbl1 as T
-- where T.i_GroupID = #group_ID and T.i_NetworkUserID = U.ID
-- )
end
and your xml generation like
var userIDs = new List<int>() { 1, 2, 3 };
var userXML = new XElement("List", a.Select(x => new XElement("ID", x))).ToString();
// so userXML = "<List><ID>1</ID><ID>2</ID><ID>3</ID></List>"
hope that helps

insert multi value with SP

I have two tables.
1- student table & 2- Score table
I want to insert value at student table & insert multi value at Score table with SP to SQL Server 2008.
for EX:
ALTER proc [dbo].[InsertIntoScore]
(
#DateReg datetime,
#stdLastName nvarchar(50),
#stdFirstName nvarchar(50),
#Description nvarchar(500),
multi value as score table...
)
AS
DECLARE #Id AS INT
BEGIN TRY
BEGIN TRANSACTION
INSERT INTO Student(DateReg,stdLastName,stdFirstName,[Description])
VALUES (#DateReg,#stdLastName,#stdFirstName,#Description)
set #Id = SCOPE_IDENTITY()
insert multi value at Score table...
COMMIT
END TRY
BEGIN CATCH
IF ##TRANCOUNT > 0
ROLLBACK
END CATCH
please help me...
You should use Table-Valued Parameters
Create a Sql Type for the table you will pass in
CREATE TYPE dbo.ScoreType AS TABLE ( ScoreID int, StudentID int, etc.... )
pass your datatable from C# code into the stored procedure using the above defined type
ALTER proc [dbo].[InsertIntoScore]
( #DateReg datetime, #stdLastName nvarchar(50), #stdFirstName nvarchar(50),
#Description nvarchar(500), #tvpScore ScoreType)
AS
.....
INSERT INTO dbo.Score (ScoreID, StudentID, ....)
SELECT dt.ScoreID, #id, .... FROM #tvpScore AS dt;
in c# pass the datatable in this way
SqlCommand insertCommand = new SqlCommand("InsertIntoScore", sqlConnection);
SqlParameter p1 = insertCommand.Parameters.AddWithValue("#tvpScore", dtScore);
p1.SqlDbType = SqlDbType.Structured;
p1.TypeName = "dbo.ScoreType";
.....
insertCommand.ExecuteNonQuery();

Resources