Stored Procedure.. using sql server - sql-server

Can any tell me how to send the LIst of IDs to the stored procedure in sql.
I need to send the List from My Controller so that that List of ID's can execute at a time using stored procedure.
Thanks

In SQL Server 2008 and up you can use Table-Valued Parameters

The best way (in 2008) is to pass it as a table. Pre 2008 you had to use a CSV format VarChar then split it out.
Have a read of this: http://www.sommarskog.se/arrays-in-sql-2008.html

What about a comma delimited string of Id's?
The problem is sql server doesn't support an array data type (or similar)

Sounds like you need something along the lines of this:
CREATE FUNCTION [dbo].[Split_String]
(
#ConcatValues VARCHAR(MAX)
)
RETURNS #Values Table
(
Value VARCHAR(MAX)
)
AS
/**************************************************************************************************************
Purpose: When called from a stored procedure and passed a character delimited parameter (of String data type values),
this function returns a table named "#Values" with a field named "Value" (populated with the parameter list)
which can then be referenced in the stored procedure.
This function requires that the delimited paramater have as its first character the delimiter character.
Sample calls:
Select * from [dbo].[Split_String](';dog;cat;mouse')
Select * from [dbo].[Split_String]('| dog| cat| mouse|')
Select * from [dbo].[Split_String]('|')
Select * from [dbo].[Split_String]('')
**************************************************************************************************************/
BEGIN
--Indexes to keep the position of searching
DECLARE #Delim CHAR(1)
Declare #Pos1 Int
Declare #Pos2 Int
--Identify delimiter character
SET #Delim = SUBSTRING(#ConcatValues, 1, 1)
--Append delimiter character
Set #ConcatValues = #ConcatValues + ' ' + #Delim
--Set 1st character of 1st value
Set #Pos2 = 2
While #Pos2 < Len(#ConcatValues)
BEGIN
Set #Pos1 = CharIndex(#Delim, #ConcatValues, #Pos2)
Insert #Values SELECT LTRIM(RTRIM(Substring(#ConcatValues, #Pos2, #Pos1 - #Pos2)))
--Go to next non-delimiter character
Set #Pos2 = #Pos1 + 1
END
RETURN
END
GO
Our split function is generic for use in a wide variety of situations and is dependent on the delimiter being identified by the first character in the string. It is likely that it could be simplified a bit if you only need it in one spot.

Related

Remove a value from a comma separated string in sql stored procedure

I have a field that store the comma separated id's of publications. Such as 123456,2345678,123567,2345890 etc. When I pull the data from the database I put it into a json object and the web page loops the values and displays the data. Works great.
What I would like to do is to send the stored proc one of the numbers and the stored proc will remove it from the string and save it back to the table. Such as the end user worked on publication 123567 and now wants to make it completed, so I want to remove it from the string so they don't see it in the future. I have a split function in the database but I don't know how to wire it up to delete or rebuild the string without the publication ID.
I don't have any code to show because I am at a loss to start. I figure I need to pass the entire string and the ID. Split the string and loop each value to rebuild a new string but check if the ID is there and skip it.
Is this the best way to do this?
Thanks for your help
what I've ended up with as the base to work from is:
ALTER FUNCTION dbo.RemovePMID (
#S VARCHAR(MAX)
,#PMID VARCHAR(15)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #T VARCHAR(50)
DECLARE #W VARCHAR(50)
SET #T = ''
WHILE len(#S) > 0
BEGIN
SET #W = left(#S, charindex(',', #S + ',') - 1)
IF charindex(#W, + #PMID) = 0
SET #T = #T + ',' + #W
SET #S = stuff(#S, 1, charindex(',', #S + ','), '')
END
RETURN substring(#T, 2, len(#T) - 2)
END
GO
No need for loops (please take a peek at Larnu's suggestion for your parse/split function)
That said, consider the following
Example
Declare #S varchar(max) = '123456,2345678,123567,2345890'
Declare #Zap varchar(50)='123456'
Select reverse(stuff(reverse(stuff(replace(','+#S+',',','+#Zap+',',','),1,1,'')),1,1,''))
Returns
2345678,123567,2345890

how to pass an int-set to sqlserver in a string to stored procedure and use it in an IN-Clause

I need to call a stored procedure like this:
exec myProcedure '(5, 15, 45)'
And inside the procedure I need to use the int-set within an in-Clasue
like this:
SELECT ... FROM table WHERE (days in #intSet)
This always bring a syntax Error in the WHERE-Clause.
(SqlServer evidently does not allow to simply replace a part of the statement by a string)
I plan a solution like this:
I can easily split the integer values of the string into several integers using
CHARINDEX, SUBSTRING, RTRIM, LTRIM, CONVERT - this is not an issue - it works fine.
But I still cannot figure out into what kind of variable could I then put those integers in order to later use it with the IN-Clause ?
any ideas are greatly appreciated
Gerald
You will need to create a split function inside you database,
Definition Of Split Function
CREATE FUNCTION [dbo].[split]
(
#delimited NVARCHAR(MAX),
#delimiter NVARCHAR(100)
)
RETURNS #t TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))
AS
BEGIN
DECLARE #xml XML
SET #xml = N'<t>' + REPLACE(#delimited,#delimiter,'</t><t>') + '</t>'
INSERT INTO #t(val)
SELECT r.value('.','varchar(MAX)') as item
FROM #xml.nodes('/t') as records(r)
RETURN
END
Stored Procedure
Then you would use this split function insdie your Procedure to split the values to be used with In operator.
CREATE PROCEDURE GetData
#intSet VARCHAR(1000) = NULL
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM TableName
WHERE days IN (SELECT Val FROM dbo.split(#intSet ))
END

TSQL update table using call for one stored procedure to another

I have the following stored procedure which returns the file size in bytes per input full file path string.
I want to write another wrapping stored procedure or function to update a table that has two columns. Column Full_Path (input for the stored procedure below) and column size (should be updated by the output from the procedure below). Basically I want to update the size column per each file (specified in the full path column) using the procedure below.
I am not sure how to do it. Please advise.
Create proc sp_get_file_size (#fileName varchar(200))
as
begin
declare #ntcmd varchar(200)
declare #detailLine varchar(200)
declare #pos1 int
declare #pos2 int
declare #size int
set nocount on
Create table #res (line varchar(400))
set #ntcmd = 'dir /-C ' + #fileName
insert #res exec xp_CmdShell #ntcmd
select #detailLine = line
from #res where rtrim(ltrim(line)) like '%bytes'
-- if detail Line is null - return -1
if isnull (#detailLine ,'*') = '*' return -1
-- get position of words bytes and File(s)
set #pos1 = charindex ('bytes' ,lower(#detailLine))
set #pos2 = charindex ('(s)' , lower(#detailLine))
-- extract the size value from the details Line
set #size = convert (int, rtrim(ltrim(
substring (#detailLine , #pos2+3,#pos1 - #pos2 - 4))))
return (#size)
set nocount off
end
go
Rewrite your stored procedure as scalar used-defined function that returns the size. Then you don't need a second stored procedure, a single update statement will do the trick:
UPDATE MyTable SET Size = fn_get_file_size(Full_Path)
(note: you will need to use table variable instead of temp table #res since temp tables aren't allowed inside of UDFs)

Create IN subquery from a VARCHAR parameter with comma separated values [duplicate]

This question already has answers here:
T-SQL stored procedure that accepts multiple Id values
(5 answers)
Closed 8 years ago.
I have a stored procedure that I need to pass a comma-delimited variable to.
For example, if a certain condition exists, I would pass a list of country codes like this:
AU,RA,PK
The number of items can vary.
In the stored procedure, I need to use those items in an IN clause such as follows:
WHERE CountryCode IN (#ExcludeCountries)
Is there any way to do this? I can massage the country codes going in to something like N'AU', N'RA', N'PK' if need be.
Thanks.
WHERE CountryCode IN (SELECT *
FROM [dbo].[ufn_CSVToTable](#ExcludeCountries,',')
This is how you can create [dbo].[ufn_CSVToTable]:
How to convert comma separated NVARCHAR to table records in SQL Server 2005?
In practice I've seen this problem resolved using the function below. This function splits the string and return a table containing the values specified. Then use it like this...
...CountryCode IN (SELECT * FROM dbo.SplitString(#ExcludeCountries ,','))
Notice that in this example the comma (',') is the delimiter. I've used this method for years and I haven't encounter any performance problems.
CREATE FUNCTION [dbo].[SplitString]
(
#SplitStr nvarchar(MAX),
#SplitChar nvarchar(5)
)
RETURNS #RtnValue table
(
Data nvarchar(MAX)
)
AS
BEGIN
Declare #Count int
Set #Count = 1
While (Charindex(#SplitChar,#SplitStr)>0)
Begin
Insert Into #RtnValue (Data)
Select
Data = ltrim(rtrim(Substring(#SplitStr,1,Charindex(#SplitChar,#SplitStr)-1)))
Set #SplitStr = Substring(#SplitStr,Charindex(#SplitChar,#SplitStr)+1,len(#SplitStr))
Set #Count = #Count + 1
End
Insert Into #RtnValue (Data)
Select Data = ltrim(rtrim(#SplitStr))
Return
END
There are two ways to do that:
Using the #ExcludeCountries parameter build table variable table that is latter join to your query
Build a dynamic SQL statement like this
... + 'WHERE CountryCode IN' (' + #ExcludeCountries + ')' ...
and then use sp_executesql to exec the statement

LPAD in SQL Server 2008

I can't see a function like LPAD in SQL Server 2008. For example how can I convert the following queries into T-SQL?
select LPAD(MY_VALUE,2,' ')) VALUE
FROM MY_TABLE
Basically pad it with the number of characters you are intending to select and then right the string.
Select right(replicate(' ',2) + YourFieldValue,2) from YourTable
You can use the space function instead of replicate, space(number_of_spaces), replicate just allows you to pad with alternative characters.
Manual calculations can be annoying to apply inside queries. Luckily, we can create a function:
CREATE FUNCTION LPAD
(
#string VARCHAR(MAX), -- Initial string
#length INT, -- Size of final string
#pad CHAR -- Pad character
)
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN REPLICATE(#pad, #length - LEN(#string)) + #string;
END
GO
(Please replace VARCHAR with NVARCHAR to your liking, or use an alternative algorithm.)
Then:
SELECT dbo.LPAD(MY_VALUE, 2, ' ') VALUE
FROM MY_TABLE
Should work since SQL Server 2005.
I've come up with a LPAD and RPAD function where you can use a characterstring for the pad-part.
They should work the same as the DB2 versions.
Here's the LPAD:
CREATE FUNCTION dbo.LPAD
(
#string NVARCHAR(MAX), -- Initial string
#length INT, -- Size of final string
#pad NVARCHAR(MAX) -- Pad string
)
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN SUBSTRING(REPLICATE(#pad, #length),1,#length - LEN(#string)) + #string;
END
GO
And here is the RPAD:
CREATE FUNCTION dbo.RPAD
(
#string NVARCHAR(MAX), -- Initial string
#length INT, -- Size of final string
#pad NVARCHAR(MAX) -- Pad string
)
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN #string + SUBSTRING(REPLICATE(#pad, #length),1,#length - LEN(#string));
END
GO
I needed something similar but I couldn't use '+' because then it was interpreted as an addition between the numbers '0000000000' and [seq_no]. So I used concat instead and it worked fine.
select right (concat(replicate('0', 10), next value for seq_no), 10);

Resources