I have variable
DECLARE #Routs NVARCHAR(1024)
#i int
SET #Routs = N'6,4,-5,8'
I need to extract any number from this sting, where it have minus sign before it (-5 in example)
and use it as input parameter with out (-) sing for example #i in different stored procedure.
Pass in you're #Routs parameter to a table valued function that will split the list into a table and then loop through the table and if the value is a negative number execute stored procedure or whatever you want or do nothing if its not negative.
--table function to split parameter by comma
ALTER FUNCTION [dbo].[SplitListOfInts] (#list nvarchar(MAX))
RETURNS #tbl TABLE (number int NOT NULL) AS
BEGIN
DECLARE #pos int,
#nextpos int,
#valuelen int
if len(rtrim(#list)) > 0
begin
SELECT #pos = 0, #nextpos = 1
WHILE #nextpos > 0
BEGIN
SELECT #nextpos = charindex(',', #list, #pos + 1)
SELECT #valuelen = CASE WHEN #nextpos > 0
THEN #nextpos
ELSE len(#list) + 1
END - #pos - 1
INSERT #tbl (number)
VALUES (convert(int, substring(#list, #pos + 1, #valuelen)))
SELECT #pos = #nextpos
END
end
RETURN
END
-- stored procedure that calls that split function and uses #routs parameter
CREATE TABLE #values(nbrValue int)
INSERT INTO #values(nbrValue
EXEC [dbo].[SplitListOfInts] #routs
--if you don't care about non-negatives delete them here
DELETE FROM #values
where nbrValue >= 0
DECLARE #i int
DECLARE #countrows = (SELECT COUNT(nbrValue) FROM #values)
WHILE #countrows >0
SET #i = (SELECT TOP 1 nbrValue FROM #values)
...do what you want
DELETE FROM #values where nbrValue=#i
set #countrows = (SELECT COUNT(nbrValue) FROM #values)
END
Related
MY text:-
CREATE proc usp_delete
#tranid int
as
begin
delete from customer where tranid in(#tranid)
end
Note:- I want to delete records more than 1 records through this stored procedure like:- if I pass 1,2,3,4,5,6 that time all 6 records should be deleted
You can use table-valued parameter for that you need to declare that
CREATE TYPE EntityId AS TABLE
( Id INT )
GO
CREATE PROCEDURE usp_delete
#tranid EntityId READONLY
AS
BEGIN
DELETE c
FROM customer c
JOIN #tranid t ON t.Id=c.tranid
END
For Executing with TVP declare a varible of type and pass it to the stored procedure
DECLARE #entityId EntityId
INSERT INTO #entityId
VALUES(1),(2),(3),(4),(5)
EXEC usp_delete #entityId
In later version of SQL Server you can use STRING_SPLIT to convert a delimited list into individual values and then join to your table using CROSS APPLY.
CREATE PROC usp_delete #tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
CROSS APPLY STRING_SPLIT(#tranid, ',')
WHERE c.tranid = value
END
GO
EXEC usp_delete '2,3,4'
In older version you can write your own table-valued function to convert a delimited string into a result set.
CREATE function [dbo].[delimited_string_to_table] (
#delimiter char(1)
, #string text
)
returns #table table (
seqnbr int not null
, string varchar(255) not null
)
as
begin
declare #pos int
declare #textpos int
declare #chunklen smallint
declare #tmpstr varchar(8000)
declare #leftover varchar(8000)
declare #tmpval varchar(8000)
declare #seq int = 1
set #textpos = 1
set #leftover = ''
while #textpos <= datalength(#string)
begin
set #chunklen = 8000 - datalength(#leftover) / 2
set #tmpstr = #leftover + substring(#string, #textpos, #chunklen)
set #textpos = #textpos + #chunklen
set #pos = charindex(#delimiter, #tmpstr)
while #pos > 0
begin
set #tmpval = ltrim(rtrim(left(#tmpstr, #pos - 1)))
insert #table (seqnbr, string) values(#seq, #tmpval)
set #tmpstr = substring(#tmpstr, #pos + 1, len(#tmpstr))
set #pos = charindex(#delimiter, #tmpstr)
set #seq = #seq + 1
end
set #leftover = #tmpstr
end
if len(rtrim(ltrim(#leftover))) != 0
insert #table(seqnbr, string) values (#seq, ltrim(rtrim(#leftover)))
return
end
GO
Which would change the example to look like this:
CREATE PROC usp_delete #tranid VARCHAR(MAX) AS
BEGIN
DELETE c
FROM customer c
JOIN dbo.delimited_string_to_table(',', #tranid)
ON c.tranid = string
END
GO
my data is :
Id Case ID#
1. QCCR1A105369, QCCR1A104986 ,QCCR1A103717
2. QCIM1A106902,4613410733 QCIM1A106902; 4613344523 QCIM1A105842; 4614004212 QCIM1A106580; 4614060189 QCIM1A106676
3. QCCR1D93616, QCCR1D92488, QCCR1D58461
4. QCCR1B40216 .... ,QCCR1B39080, QCCR1B40216, QCCR1B39745, QCCR1B38463 , QCCR1B38618, QCCR1B38619, QCCR1B38620, QCCR1B38621, QCCR1B38622, QCCR1B38465, QCCR1B38623
5. QCCR2A30221 QCCR2A30223 QCCR2A30222 QCIM2A30416
My output will be Id 1,3,4,5. I want only that rows, which have starting value QC not any numeric value. For ID 2 you can see there are some numeric values, please tell me how can I achieve it.
You could use a table valued function to split your value by a delimiter like this:
CREATE FUNCTION [dbo].[Split]
(
#ItemList NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #ItemTable TABLE (Item VARCHAR(250))
AS
BEGIN
DECLARE #tempItemList NVARCHAR(MAX)
SET #tempItemList = #ItemList
DECLARE #i INT
DECLARE #Item NVARCHAR(4000)
SET #i = CHARINDEX(#delimiter, #tempItemList)
WHILE (LEN(#tempItemList) > 0)
BEGIN
IF #i = 0
SET #Item = #tempItemList
ELSE
SET #Item = LEFT(#tempItemList, #i - 1)
INSERT INTO #ItemTable(Item) VALUES(#Item)
IF #i = 0
SET #tempItemList = ''
ELSE
SET #tempItemList = RIGHT(#tempItemList, LEN(#tempItemList) - #i)
SET #i = CHARINDEX(#delimiter, #tempItemList)
END
RETURN
END
Then this query returns the expected result:
SELECT t.*
FROM dbo.TableName t
WHERE NOT EXISTS
(
SELECT 1 FROM dbo.Split(t.CaseID, ',') split
WHERE NOT LEFT(LTRIM(split.Item), 2) = 'QC'
OR ISNUMERIC(split.Item) = 1
)
Demo with your sample data. But in general you should avoid multiple values in one column. Instead store it in separate rows in a linked table. That's called database normalization.
I am looking for a way, that I can convert lines of a text in separate records. Perhaps there is someone who has an idea?
I have the following record in a table:
1 blabla Messe\nJahr\nLand
The third field is a textfield. The content is a text with three lines.
now, I should write a select, which gives me as a result three records
1 Memo
2 Jahr
3 Land
i suggest using a cursor and then splitting the string using charpos. as i did not know the name of your table or column, i used table name a, column name a.
declare c cursor for
select a
from a
declare #p varchar(max)
open c
fetch next from c into #p;
while ##FETCH_STATUS = 0
begin
while CHARINDEX('\n',#p,0) > 0
begin
select SUBSTRING(#p,0,charindex('\n',#p,0))
set #p = SUBSTRING(#p,charindex('\n',#p,0)+2, LEN(#p)-charindex('\n',#p,0)-1);
end
select #p;
fetch next from c into #p;
end
DEALLOCATE c
i tested this using
create table a (a varchar(50))
insert into a values ('a\nb\nc')
insert into a values ('d\ne\nf')
use this..
ALTER FUNCTION [dbo].[GetWordsFromString]
(
#string nvarchar(max)
)
RETURNS
#out TABLE
(
Name nvarchar(200)
)
AS
BEGIN
DECLARE #pos int,
#nextpos int,
#valuelen int
SELECT #pos = 0, #nextpos = 1
WHILE #nextpos > 0
BEGIN
SELECT #nextpos = charindex('\', #string, #pos + 1)
SELECT #valuelen = CASE WHEN #nextpos > 0
THEN #nextpos
ELSE len(#string) + 1
END - #pos - 1
INSERT #out
VALUES (convert(nvarchar, substring(#string, #pos + 1, #valuelen)))
SELECT #pos = #nextpos
END
RETURN
END
I need your help regarding the following situation in SQL Server 2008R2.
In SQL, I have a list of ids saved as NVARCHAR(MAX) like N('1,2,3,4,5')
I read this How to convert comma separated NVARCHAR to table records in SQL Server 2005?
In this scope, I wrote a function for this:
ALTER FUNCTION [dbo].[func$intlist_to_tbl] (#list nvarchar(MAX))
RETURNS #tbl TABLE (number int NOT NULL) AS
BEGIN
DECLARE #pos int,
#nextpos int,
#valuelen int
SELECT #pos = 0, #nextpos = 1
WHILE #nextpos > 0
BEGIN
SELECT #nextpos = charindex(',', #list, #pos + 1)
SELECT #valuelen = CASE WHEN #nextpos > 0
THEN #nextpos
ELSE len(#list) + 1
END - #pos - 1
INSERT #tbl (number)
VALUES (convert(int, substring(#list, #pos + 1, #valuelen)))
SELECT #pos = #nextpos
END
RETURN
END
Ok, I want to delete some records which id IS NOT found in above list.
How to do that ?
I tried something like:
DELETE a_ FROM TableA a_
LEFT JOIN func$intlist_to_tbl(#idList) _tmp
ON _tmp.number = a_.ID_
WHERE a_.ID IS NULL
But is not correct.
Maybe something similar?
DELETE FROM
TableA a_
where
a_.id not in (select number from func$intlist_to_tbl(#idList))
The user selects various words from a drop down list and these values get added into a comma delimited string. When passing the string to a stored procedure I want it to select * from a table where that word exists.
Table
id----word
1-----cat
2-----dog
3-----mouse
4-----dog
string that is passed into the stored procedure is cat, dog so returning columns 1, 2 and 4.
Is there a way of doing this in sql server?
Use IN:
SELECT *
FROM your_table
WHERE word IN ('cat', 'dog')
you first need to make a function SplitCSV :
CREATE FUNCTION [dbo].[SplitCSV] (#CSVString VARCHAR(8000), #Delimiter CHAR(1))
RETURNS #temptable TABLE (items VARCHAR(8000))
AS
BEGIN
DECLARE #pos INT;
DECLARE #slice VARCHAR(8000);
SELECT #pos = 1;
IF LEN(#CSVString) < 1 OR #CSVString IS NULL RETURN;
WHILE #pos!= 0
BEGIN
SET #pos = CHARINDEX(#Delimiter,#CSVString);
IF #pos != 0
SET #slice = LEFT(#CSVString, #pos - 1);
ELSE
SET #slice = #CSVString;
IF( LEN(#slice) > 0)
INSERT INTO #temptable(Items) VALUES (#slice);
SET #CSVString = RIGHT(#CSVString, LEN(#CSVString) - #pos);
IF LEN(#CSVString) = 0 BREAK;
END
RETURN
END
GO
then you can use it like :
SELECT *
FROM myTable
WHERE ID IN (
SELECT items FROM [dbo].[SplitCSV]('1,2,3,4,5', ',')
)
SELECT *
FROM Table
WHERE '%,' + Word + ',%' LIKE ',' + #your_csv_param + ','
Extra commas at the begin and end of parameter and column are to prevent search to match cat with catfish for example.
If you want select all animal except mouse , you can use NOT IN
SELECT * FROM
TABLE
WHERE Word Not IN('Mouse')
So you can avoid type many type of animal
CREATE FUNCTION
ALTER FUNCTION [dbo].[fn_Split](#text varchar(8000), #delimiter varchar(20) = ' ')
RETURNS #Strings TABLE
(
position int IDENTITY PRIMARY KEY,
value varchar(8000)
)
AS
BEGIN
DECLARE #index int
SET #index = -1
WHILE (LEN(#text) > 0)
BEGIN
SET #index = CHARINDEX(#delimiter , #text)
IF (#index = 0) AND (LEN(#text) > 0)
BEGIN
INSERT INTO #Strings VALUES (#text)
BREAK
END
IF (#index > 1)
BEGIN
INSERT INTO #Strings VALUES (LEFT(#text, #index - 1))
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
ELSE
SET #text = RIGHT(#text, (LEN(#text) - #index))
END
RETURN
END
----
select * from yourtable where column in ( select value from fn_Split(#para1,',')