insert collection of data into sql server columns with storedprocedure - sql-server

i'm begginer in sql server
i want to insert collection of data into the column in stored procedure
i want pass data from c# like this (100,'3,5,4,2,9') and insert to the column like this
ID Number
100 3
100 5
100 4
100 2
100 9
My procedure code
ALTER PROCEDURE [dbo].[Number]
#Number CHAR(10),
AS
BEGIN
BEGIN TRY
INSERT INTO NumbersTbl
VALUES(#Number)
SELECT 1
END TRY
BEGIN CATCH
EXEC SQLError
SELECT -1
END CATCH
END
how i can do it?
thank you

Procedure Definition
ALTER PROCEDURE [dbo].[Number]
#Value INT,
#Number Varchar(100),
#Sucecc BIT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
DECLARE #xml xml;
BEGIN TRY
SET #xml = cast(('<X>'+replace(#Number,',' ,'</X><X>')+'</X>') as xml)
INSERT INTO NumbersTbl (Column1 , Column2)
SELECT #Value, N.value('.', 'varchar(100)') as value
FROM #xml.nodes('X') as T(N)
SET #Sucecc = 1;
END TRY
BEGIN CATCH
EXEC SQLError
SET #Sucecc = 0;
END CATCH
END
Call Procedure
DECLARE #Result BIT;
Exec [dbo].[Number] #Value = 100
,#Number = '3,5,4,2,9'
,#Sucecc = #Result OUTPUT

First you can create the special function to parse input numbers:
CREATE FUNCTION dbo.splitstring ( #stringToSplit VARCHAR(MAX) )
RETURNS
#returnList TABLE ([Numbers] [nvarchar] (500))
AS
BEGIN
DECLARE #name NVARCHAR(255)
DECLARE #pos INT
WHILE CHARINDEX(',', #stringToSplit) > 0
BEGIN
SELECT #pos = CHARINDEX(',', #stringToSplit)
SELECT #name = SUBSTRING(#stringToSplit, 1, #pos-1)
INSERT INTO #returnList
SELECT #name
SELECT #stringToSplit = SUBSTRING(#stringToSplit, #pos+1, LEN(#stringToSplit)-#pos)
END
INSERT INTO #returnList
SELECT #stringToSplit
RETURN
END
And then edit your procedure:
ALTER PROCEDURE [dbo].[Number]
#ID INT,
#Number VARCHAR(MAX)
AS
BEGIN
BEGIN TRY
INSERT INTO NumbersTbl(ID, Number)
SELECT #ID, Numbers
FROM dbo.splitstring(#Number)
END TRY
BEGIN CATCH
EXEC SQLError
SELECT -1
END CATCH
END
Call: EXEC Number 100,'3,5,4,2,9'

Related

Have anyone a solution to send row parameter to a stored prodedure in MS-SQL Server with dynamic Column Arrangement?

I Could write a trigger for a table that is able to detect updated columns and logs the changes. I want to make a stored procedure from this trigger and call it when required. But I do not know how can I send "inserted" or "updated" rows that are valid in trigger body, to this SP.
Here is my trigger :
CREATE TRIGGER [dbo].[tgr_MyTable_TransactionLogUpdate]
ON [dbo].[MyTable]
AFTER UPDATE
AS
BEGIN
if (select F_SharhRadif from [Payeh.Decode] where F_ShJadval=18 and F_ShRadif=1)='2'
begin
return
end
declare #userid int=(select top 1 userid from inserted)
declare #computername nvarchar(50)=(select top 1 computername from inserted)
declare #ip nvarchar(50)=(select top 1 IP from inserted)
declare #zamantaqeer datetime=(select top 1 F_ZamanTaqeer from inserted)
declare #changetime =GETDATE()
DECLARE #tableID BIGINT=(SELECT id FROM sys.sysobjects WHERE [name]='MyTable')
DECLARE #ColCount INT=(SELECT COUNT(*) FROM sys.syscolumns WHERE id=#tableID)
DECLARE #ColIndex INT=1
DECLARE #UpdateDetails NVARCHAR(MAX)=''
DECLARE #ColName NVARCHAR(1000)
DECLARE #ByteIndex INT
SELECT * INTO #d FROM deleted
SELECT * INTO #i FROM inserted
WHILE (#ColIndex<=#ColCount)
BEGIN
--IF (COLUMNS_UPDATED()&POWER(2,#ColIndex-1) <> 0)
SET #ByteIndex=((#ColIndex-1)/8)+1
IF (CONVERT(INT,SUBSTRING(COLUMNS_UPDATED(),#ByteIndex,1))&POWER(2,((#ColIndex-1)%8)) <> 0)
BEGIN
SET #ColName=(SELECT [name] FROM sys.syscolumns WHERE id=#tableID AND colid=#ColIndex)
DECLARE #OldValue NVARCHAR(MAX)
DECLARE #NewValue NVARCHAR(MAX)
DECLARE #ParmDefinition NVARCHAR(100)=N'#DeletedValue NVARCHAR(MAX) OUTPUT'
DECLARE #SQL NVARCHAR(1000)='SELECT #DeletedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #d'
EXEC sp_executesql #SQL,#ParmDefinition,#DeletedValue=#OldValue OUTPUT
SET #ParmDefinition = N'#InsertedValue NVARCHAR(MAX) OUTPUT'
SET #SQL= 'SELECT #InsertedValue=LTRIM(RTRIM(CONVERT(nvarchar(MAX),'+#ColName+'))) FROM #i'
EXEC sp_executesql #SQL,#ParmDefinition,#InsertedValue=#NewValue OUTPUT
IF (#OldValue<>#NewValue)
BEGIN
SET #UpdateDetails=#UpdateDetails+#ColName+': OLD="'+ #OldValue+'" -New="'+#NewValue+'", '
END
END
SET #ColIndex=#ColIndex+1
END
IF (LEN(#UpdateDetails)>0)
BEGIN
SET #UpdateDetails=SUBSTRING(#UpdateDetails,1,LEN(#UpdateDetails)-1)
END
ELSE
BEGIN
SET #UpdateDetails='No Changes'
END
--[User.TransactionLog] is the name of the table that stores the history of changes
INSERT INTO [User.TransactionLog]
([Tablename],[OperationType],[Desciption],[UserID],[ComputerName],[IP],[ChangeTime])
SELECT 'MyTable',2,#UpdateDetails,'',#userid,#computername,#ip, #changetime
DROP TABLE #d
DROP TABLE #i

T-SQL 2008- Exit when Value is NULL

I am looking for a way to exit an T-SQL script when #Value is null. This is what I have so far but it does not work as expected:
SELECT
#Value,
CASE
WHEN #Value IS NULL
RAISERROR('EXIT', 16, 1)
FROM
table
WHERE
name LIKE 'test'
Perhaps this will work for you:
DECLARE #Value INT = 1
IF( #Value IS NULL)
BEGIN
RAISERROR('Exit',16,1)
END
ELSE
BEGIN
SELECT #Value
END
IF #Value IS NULL RAISERROR('EXIT', 16,1);
Using a cursor and a temp table you can get the output you want. don't know if that's the goal,
USE AdventureWorksLT2012
DECLARE #CustomerID AS INT
DECLARE #CompanyName AS VARCHAR(MAX)
DECLARE #EmailAddress AS VARCHAR(MAX)
CREATE TABLE #output (CustomerID INT,CompanyName VARCHAR(MAX),EmailAddress VARCHAR(MAX))
DECLARE testCursor CURSOR
FOR
SELECT TOP (100)
CustomerID
,CompanyName
,EmailAddress
FROM SalesLT.Customer
ORDER BY customerID DESC;
OPEN testCursor;
FETCH NEXT FROM testCursor
INTO #CustomerID, #CompanyName, #emailAddress;
if #EmailAddress is not null
BEGIN
INSERT INTO #output values( #CustomerID, #CompanyName, #emailAddress);
WHILE ##FETCH_STATUS = 0
BEGIN
FETCH NEXT FROM testCursor
INTO #CustomerID, #CompanyName, #emailAddress;
if #EmailAddress is null
BEGIN
RAISERROR('Exit',16,1);
BREAK;
end
INSERT INTO #output values( #CustomerID, #CompanyName, #emailAddress);
END;
END
CLOSE testCursor;
DEALLOCATE testCursor;
SELECT * FROM #output;
DROP TABLE #output

When Called Main Stored Procedure From Function Gives Subprocedure Results in DataTable

I have a sql stored procedure which calls another sql stored procedure. I works fine when excuted in sql server. But when I called from function in class it returns the DataTable returned by subprocedure. I want to return data returned by main procedure.
My Main Procedure:
ALTER PROCEDURE [dbo].[StoredProcedure2]
#QuaterList varchar(50) = NULL
AS
BEGIN
DECLARE #sql nvarchar(4000)
SELECT #sql='SELECT Id, Suggester, Requester, Date_Created from CRM.dbo.CRM_Doctor_Request WHERE 1=1 '
If (#QuaterList) IS NOT NULL
BEGIN
DECLARE #MonthsList varchar(1000)
EXEC dbo.SPGetMonthsListforMultipleQuaters #QuaterList, #MonthsList OUTPUT
SELECT #MonthsList
SELECT #sql=#sql + ' AND MONTH(Date_Created) in ('
+ SUBSTRING(#MonthsList, 1, LEN(#MonthsList)-1) +')'
END
EXEC sp_executesql #sql, N' #QuaterList varchar(50) ',
#QuaterList
END
Sub Procedure SPGetMonthsListforMultipleQuaters:
ALTER PROCEDURE dbo.SPGetMonthsListforMultipleQuaters
#InputList varchar(10),
#MonthsList varchar(1000) OUTPUT
AS
BEGIN
SELECT #MonthsList= ''
/* Create temp table */
CREATE TABLE #TempListTable
(
TableField int
)
/* add data into temp table */
DECLARE #TableField varchar(10), #Pos int
SET #InputList = LTRIM(RTRIM(#InputList))+ ','
SET #Pos = CHARINDEX(',', #InputList, 1)
IF REPLACE(#InputList, ',', '') <> ''
BEGIN
WHILE #Pos > 0
BEGIN
SET #TableField = LTRIM(RTRIM(LEFT(#InputList, #Pos - 1)))
IF #TableField <> ''
BEGIN
INSERT INTO #TempListTable (TableField) VALUES (CAST(#TableField AS int)) --Use Appropriate conversion
END
SET #InputList = RIGHT(#InputList, LEN(#InputList) - #Pos)
SET #Pos = CHARINDEX(',', #InputList, 1)
END
END
/* fetch data from temptable using cursor */
DECLARE #ArrayItem nvarchar(100)
DECLARE #Array_Cursor CURSOR
SET #Array_Cursor = CURSOR FAST_FORWARD FOR select TableField
from #TempListTable
OPEN #Array_Cursor
FETCH NEXT FROM #Array_Cursor INTO #ArrayItem
WHILE ##FETCH_STATUS = 0
BEGIN
/* creating list of months */
IF (#ArrayItem = 1)
SELECT #MonthsList=#MonthsList + '4,5,6,'
IF (#ArrayItem = 2)
SELECT #MonthsList=#MonthsList + '7,8,9,'
IF (#ArrayItem = 3)
SELECT #MonthsList=#MonthsList + '10,11,12,'
IF (#ArrayItem = 4)
SELECT #MonthsList=#MonthsList + '1,2,3,'
FETCH NEXT FROM #Array_Cursor INTO #ArrayItem
END
/*print #MonthsList*/
Close #Array_Cursor
deallocate #Array_Cursor
END
Problem solved. It was because I wrote SELECT #MonthsList so it was returning that too which is not required, and was also creating problems. So I removed it and problem solved.
New Procedure code is :
ALTER PROCEDURE [dbo].[StoredProcedure2]
#QuaterList varchar(50) = NULL
AS
BEGIN
DECLARE #sql nvarchar(4000)
SELECT #sql='SELECT Id, Suggester, Requester, Date_Created from CRM.dbo.CRM_Doctor_Request WHERE 1=1 '
If (#QuaterList) IS NOT NULL
BEGIN
DECLARE #MonthsList varchar(1000)
EXEC dbo.SPGetMonthsListforMultipleQuaters #QuaterList, #MonthsList OUTPUT
SELECT #sql=#sql + ' AND MONTH(Date_Created) in ('
+ SUBSTRING(#MonthsList, 1, LEN(#MonthsList)-1) +')'
END
EXEC sp_executesql #sql, N' #QuaterList varchar(50) ',
#QuaterList
END

Conversion failed in cursor in stored procedure

Input like 111111 and 101,102,103,104
I want to check whether user has access on this requests or not...
I tried a cursor as shown, but I get this error:
Conversion failed when converting the varchar value '101,102,103,104' to data type int.
Code:
ALTER PROCEDURE [dbo].[ValidateRqstId]
#UserID VARCHAR(50),
#RsqtIDs VARCHAR(300)
AS
BEGIN
Declare #RqstId int
Declare #Result int
Declare #UserIDToCheck VARCHAR(50)
Declare #RqstUserVal cursor for
Select RequestId
from REQUEST_LIST
where RequestId in (#RsqtIDs)
BEGIN
OPEN RqstUserVal
FETCH NEXT from RqstUserVal into #RqstId
WHILE(##fetch_status <> -1)
BEGIN
SET #UserIDToCheck = (
select UserId from dbo.REQUEST_LIST where RequestId = #RqstId)
Print(#UserIDToCheck)
If(#UserIDToCheck != #UserID)
SET #Result = 99 ;
--Fetch the next row from the cursor
FETCH RqstUserVal into #RqstId
END
END
CLOSE RqstUserVal
Deallocate RqstUserVal
RETURN #Result
END
Thanks in advance
Depending on your SQL-Server Verion you can use a Table-Valued Function like in this short example
Select * from dbo.test1
Where ID in(
Select * from dbo.F_SplitAsIntTable('1,123,234,456'))
Function defined as
CREATE FUNCTION F_SplitAsIntTable
(
#txt varchar(max)
)
RETURNS
#tab TABLE
(
ID int
)
AS
BEGIN
declare #i int
declare #s varchar(20)
Set #i = CHARINDEX(',',#txt)
While #i>1
begin
set #s = LEFT(#txt,#i-1)
insert into #tab (id) values (#s)
Set #txt=RIGHT(#txt,Len(#txt)-#i)
Set #i = CHARINDEX(',',#txt)
end
insert into #tab (id) values (#txt)
RETURN
END
GO

Input variables as stored procedure statement

My stored procedure:
ALTER PROCEDURE [dbo].[Perdate]
#D_Data as nvarchar(999)
AS
SELECT 'Total'= SUM(CAST(TBL_Stock.R_TotalPrice as decimal(18,2))),(convert(varchar,TBL_Stock.D_Datepush,105)) as Date
FROM TBL_Stock
GROUP BY (convert(varchar,TBL_Stock.D_Datepush,105))
Having (convert(varchar,TBL_Stock.D_Datepush,105)) = #D_Data
I would like to know if it is possible to set that variable (#D_Data) as something like:
'02-03-2012' or (convert(varchar,TBL_Stock.D_Datepush,105)) = '02-04-2012'
So the having clause would be :
HAVING (convert(varchar, TBL_Stock.D_Datepush, 105)) = '02-03-2012'
OR (convert(varchar, TBL_Stock.D_Datepush, 105)) = '02-04-2012'
So my idea is to have (in my VB.net project) a string that could dynamically change the stored procedure "Future"
Seems like you want to do SQL injection so that your input param "glues into" the TSQL that is being built in your proc. THIS IS A VERY BAD IDEA ( see SQL Injection discussion here).
But good news, dynamic SQL is not needed. Use a table function to parse the incoming string so that it can be joined in the proc.
create table TBL_Stock(R_TotalPrice decimal(18,2), D_Datepush datetime)
insert into TBL_Stock(R_TotalPrice,D_datepush) values(1000,'1/1/2012')
insert into TBL_Stock(R_TotalPrice,D_datepush) values(200,'1/2/2012')
insert into TBL_Stock(R_TotalPrice,D_datepush) values(30,'1/3/2012')
insert into TBL_Stock(R_TotalPrice,D_datepush) values(4,'1/4/2012')
GO
CREATE FUNCTION dbo.SplitDates(#String varchar(8000), #Delimiter char(1))
returns #temptable TABLE (dt datetime)
as
begin
declare #idx int
declare #slice varchar(8000)
select #idx = 1
if len(#String)<1 or #String is null return
while #idx!= 0
begin
set #idx = charindex(#Delimiter,#String)
if #idx!=0
set #slice = left(#String,#idx - 1)
else
set #slice = #String
if(len(#slice)>0 AND isDate(#slice) = 1)
insert into #temptable(dt) values(#slice)
set #String = right(#String,len(#String) - #idx)
if len(#String) = 0 break
end
return
end
GO
--test function
select * from dbo.SplitDates('1/1/2012,1/2/2012',',')
GO
create PROCEDURE Perdate #D_Data as nvarchar(2000)
AS
select
PushDate=z.dt,
'Total'= SUM(s.R_TotalPrice)
from
dbo.splitDates(#D_Data,',') z
join TBL_Stock s on s.D_datepush = z.dt
group by
z.dt
GO
--Test proc
select * from TBL_Stock
exec Perdate '1/1/2012'
exec Perdate '1/1/2012,1/2/2012'
exec Perdate '1/1/2012,1/4/12'

Resources