How to pass Concatenation String in IN SQL value - sql

how to pass the concatenation String into SQL SELECT IN () ?
DECLARE #NextString NVARCHAR(40)
DECLARE #Pos INT
DECLARE #NextPos INT
DECLARE #String NVARCHAR(40)
DECLARE #Delimiter NVARCHAR(40)
SET #String ='1,2'
SET #Delimiter = ','
SET #String = #String + #Delimiter
SET #Pos = charindex(#Delimiter,#String)
WHILE (#pos <> 0)
BEGIN
SET #NextString = substring(#String,1,#Pos - 1)
SELECT #NextString -- Show Results
SET #String = substring(#String,#pos+1,len(#String))
SET #pos = charindex(#Delimiter,#String)
SELECT ADRESSE, AGENCE, AUTRE_REF, CHAUFFEUR, CODE_CLIENT, CODE_DEST, CODE_MAG, CP, CREE_PAR, DATE_CLOTUR, DATE_CREE, DATE_MODIF, EMAIL, ENLEV_CREMB, ENLEV_DECL, ENLEV_UNITE, FACTURATION, FAX, INSEE, LIVRS_EXPRS, LIVRS_SAMD, LIVRS_SIGN, MODAL_MODE, MODAL_PORT, MODAL_SPEC, MODIF_PAR, NBR_COLIS, NO_ORDRE, OBS, PAYS, POID, POID_COR, REF_EXPED, RS_NOM, SIRET, STATUT_ORDRE, TEL, TRANSPORTEUR, VILLE FROM ORDRE WHERE (STATUT_ORDRE = 2) AND (TRANSPORTEUR IN (#NextString))
END
i tried with this, but in not work exactly what i expected.
Thanks you in advance,
Stev

if you know how many parameters in #NextString, you can use
TRANSPORTEUR IN (#parm1,#parm2,#parm3......)
OR you need to use the exec to execute the sql
declare #sql varchar(max)
set #sql='SELECT ADRESSE, AGENCE, AUTRE_REF,
CHAUFFEUR, CODE_CLIENT, CODE_DEST,
CODE_MAG, CP, CREE_PAR, DATE_CLOTUR,
DATE_CREE, DATE_MODIF, EMAIL,
ENLEV_CREMB, ENLEV_DECL, ENLEV_UNITE, FACTURATION,
FAX, INSEE, LIVRS_EXPRS, LIVRS_SAMD, LIVRS_SIGN,
MODAL_MODE, MODAL_PORT, MODAL_SPEC, MODIF_PAR, NBR_COLIS,
NO_ORDRE, OBS, PAYS, POID, POID_COR, REF_EXPED, RS_NOM, SIRET, STATUT_ORDRE, TEL, TRANSPORTEUR, VILLE FROM ORDRE WHERE (STATUT_ORDRE = 2) AND (TRANSPORTEUR IN (' + #NextString + '))'
exec (#sql)
and you should set the #NextString as '''p1'',''p2'',''p3'''
==================================================================================
update on 11-Jan-2013
create the spiting function
CREATE FUNCTION [dbo].[udf_Split]
( #Words nvarchar(MAX)
, #splitStr varchar(50)
)
RETURNS #Result_Table TABLE
(
[word] nvarchar(max) NULL
)
BEGIN
Declare #TempStr nvarchar(MAX)
WHILE (CHARINDEX(#splitStr,#Words)>0)
BEGIN
Set #TempStr=SUBSTRING(#Words,1,CHARINDEX(#splitStr,#Words)-1)
Insert into #Result_Table (word) Values (rtrim(ltrim(#TempStr)))
Set #Words = REPLACE(#Words,#TempStr+#splitStr,'')
END
IF(LEN(RTRIM(LTRIM(#Words)))>0 And CHARINDEX(#splitStr,RTRIM(LTRIM(#Words)))=0)
Begin
Set #TempStr=#Words
Insert into #Result_Table (word) Values (rtrim(ltrim(#TempStr)))
End
RETURN
END
then using join instead of using in
SELECT ADRESSE,
AGENCE,
AUTRE_REF,
CHAUFFEUR,
CODE_CLIENT,
CODE_DEST,
CODE_MAG,
CP,
CREE_PAR,
DATE_CLOTUR,
DATE_CREE,
DATE_MODIF,
EMAIL,
ENLEV_CREMB,
ENLEV_DECL,
ENLEV_UNITE,
FACTURATION,
FAX,
INSEE,
LIVRS_EXPRS,
LIVRS_SAMD,
LIVRS_SIGN,
MODAL_MODE,
MODAL_PORT,
MODAL_SPEC,
MODIF_PAR,
NBR_COLIS,
NO_ORDRE,
OBS,
PAYS,
POID,
POID_COR,
REF_EXPED,
RS_NOM,
SIRET,
STATUT_ORDRE,
TEL,
TRANSPORTEUR,
VILLE
FROM ORDRE a
INNER JOIN udf_split(#NextString, ',') b
ON b.word = a.TRANSPORTEUR
WHERE (STATUT_ORDRE = 2)

Related

SQL - split a string using "/" that occurs multiple times

I'm looking for a query for HSQLDB.
I have a string that contains address information delimited by "/". Now I have to split this string by "/" and insert individual address information into separate columns.
Address = /1234/CLAREVIEW////WILMINGTON/DE/19702
This needs to be split as
StreetNo = Address[1] = 1234
StreetName = Address[2] = CLAREVIEW
StreetType = Address[3] =
City = Address[6] = WILMINGTON
StateCd = Address[7] = DE
ZipCd = Address[8] = 19702
How can i achieve this?
CREATE PROCEDURE with the REGEXP_SUBSTRING_ARRAY function to split into an array.
REGEXP_SUBSTRING_ARRAY('/1234/CLAREVIEW////WILMINGTON/DE/19702', '/\p{Alnum}*');
Returns
ARRAY['/1234','/CLAREVIEW','/','/','/','/WILMINGTON','/DE','/19702']
So the procedure should contain:
CREATE PROCEDURE INSERT_USING_REGEXP (p1 VARCHAR(500))
BEGIN ATOMIC
DECLARE arr VARCHAR(200) ARRAY;
SET arr = REGEXP_SUBSTRING_ARRAY(p1,'/\p{Alnum}*');
INSERT INTO thetable ((StreetNo, StreetName, StreetType...) VALUES ( arr[1], arr[2], arr[3], ...);
END;
Then
CALL INSERT_USING_REGEXP('/1234/CLAREVIEW////WILMINGTON/DE/19702');
CREATE TABLE #Results
(
Ordinal NUMERIC,
StringValue VARCHAR(MAX)
)
DECLARE #String VARCHAR(100),
#Delimiter VARCHAR(100)
SET #String = '/1234/CLAREVIEW////WILMINGTON/DE/19702'
SET #Delimiter = '/'
DECLARE #TempString VARCHAR(MAX) = #String,
#Ordinal INT = 0,
#CharIndex INT = 0
SET #CharIndex = CHARINDEX(#Delimiter, #TempString)
WHILE #CharIndex != 0
BEGIN
SET #Ordinal += 1
INSERT #Results
VALUES (#Ordinal, SUBSTRING(#TempString, 0, #CharIndex))
SET #TempString = SUBSTRING(#TempString, #CharIndex + 1, LEN(#TempString) - #CharIndex)
SET #CharIndex = CHARINDEX(#Delimiter, #TempString)
END
IF #TempString != ''
BEGIN
SET #Ordinal += 1
INSERT #Results
VALUES (#Ordinal, #TempString)
END
SELECT *
FROM #Results
I took this answer from here but it should do the trick

need splitting a variable into 6 variables - SQL

need help filling in the blanks i am struggling with splitting a variable into 6 variables.
DECLARE #item VARCHAR(MAX) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(MAX)
DECLARE #item2 VARCHAR(MAX)
DECLARE #item3 VARCHAR(MAX)
DECLARE #item4 VARCHAR(MAX)
DECLARE #item5 VARCHAR(MAX)
DECLARE #item6 VARCHAR(MAX)
set #item1 = (SUBSTRING( #item, 0, CHARINDEX('.', #item)))
set #item2 = (SUBSTRING(SUBSTRING( #item, CHARINDEX('.', #item)+1,LEN(#ITEM)),0,CHARINDEX('.', SUBSTRING( #item, CHARINDEX('.', #item)+1,LEN(#ITEM))) ))
set #item6 = (REVERSE(SUBSTRING( REVERSE(#ITEM), 0, CHARINDEX('.' , REVERSE(#ITEM)))))
print #item1
print #item2
print #item3
print #item4
print #item5
print #item6
Just about any String Parser will do. That said, I have one that will return (currently) up to 9 variables
Select #item1=Pos1
,#item2=Pos2
,#item3=Pos3
,#item4=Pos4
,#item5=Pos5
,#item6=Pos6
From [dbo].[udf-Str-Parse-Row](#Item,'.')
The UDF
CREATE FUNCTION [dbo].[udf-Str-Parse-Row] (#String varchar(max),#Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse-Row]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse-Row]('John Cappelletti',' ')
-- Select * from [dbo].[udf-Str-Parse-Row]('id26,id46|id658,id967','|')
Returns Table
As
Return (
SELECT Pos1 = xDim.value('/x[1]','varchar(250)')
,Pos2 = xDim.value('/x[2]','varchar(250)')
,Pos3 = xDim.value('/x[3]','varchar(250)')
,Pos4 = xDim.value('/x[4]','varchar(250)')
,Pos5 = xDim.value('/x[5]','varchar(250)')
,Pos6 = xDim.value('/x[6]','varchar(250)')
,Pos7 = xDim.value('/x[7]','varchar(250)')
,Pos8 = xDim.value('/x[8]','varchar(250)')
,Pos9 = xDim.value('/x[9]','varchar(250)')
FROM (Select Cast('<x>' + Replace(#String,#Delimeter,'</x><x>')+'</x>' as XML) as xDim) A
)
Here is a simpler way using XML trick
DECLARE #item VARCHAR(max) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(max)
DECLARE #item2 VARCHAR(max)
DECLARE #item3 VARCHAR(max)
DECLARE #item4 VARCHAR(max)
DECLARE #item5 VARCHAR(max)
DECLARE #item6 VARCHAR(max);
WITH split_names
AS (SELECT CONVERT(XML, '<Names><name>' + Replace(#item, '.', '</name><name>') + '</name></Names>') AS xmlname)
SELECT #item1 = xmlname.value('/Names[1]/name[1]', 'varchar(50)'),
#item2 = xmlname.value('/Names[1]/name[2]', 'varchar(50)'),
#item3 = xmlname.value('/Names[1]/name[3]', 'varchar(50)'),
#item4 = xmlname.value('/Names[1]/name[4]', 'varchar(50)'),
#item5 = xmlname.value('/Names[1]/name[5]', 'varchar(50)'),
#item6 = xmlname.value('/Names[1]/name[6]', 'varchar(50)')
FROM split_names
Why not use this pattern?
set #item1 = SUBSTRING_INDEX( #item, '.', 1)
.
set #item3 = SUBSTRING_INDEX( SUBSTRING_INDEX( #item, '.', 2), '.', 1)
.
.
set #item6 = SUBSTRING_INDEX( #item, '.', -1)
I am assuming by 6 variables you mean each substring between the dots in #item is a separate "variable".
A more generic parser could be as follows. This one returns a row number and is not limited as to depth.
DECLARE #item VARCHAR(MAX) = 'MG1111.TG2222.MW3333.JG4444.MG5555.MH6666'
DECLARE #item1 VARCHAR(MAX)
DECLARE #item2 VARCHAR(MAX)
DECLARE #item3 VARCHAR(MAX)
DECLARE #item4 VARCHAR(MAX)
DECLARE #item5 VARCHAR(MAX)
DECLARE #item6 VARCHAR(MAX)
Select #item1=max(case when Key_PS=1 then Key_Value else '' end)
,#item2=max(case when Key_PS=2 then Key_Value else '' end)
,#item3=max(case when Key_PS=3 then Key_Value else '' end)
,#item4=max(case when Key_PS=4 then Key_Value else '' end)
,#item5=max(case when Key_PS=5 then Key_Value else '' end)
,#item6=max(case when Key_PS=6 then Key_Value else '' end)
From [dbo].[udf-Str-Parse](#Item,'.')
The UDF
CREATE FUNCTION [dbo].[udf-Str-Parse] (#String varchar(max),#Delimeter varchar(10))
--Usage: Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
-- Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
Returns #ReturnTable Table (Key_PS int IDENTITY(1,1), Key_Value varchar(max))
As
Begin
Declare #XML xml;Set #XML = Cast('<x>' + Replace(#String,#Delimeter,'</x><x>')+'</x>' as XML)
Insert Into #ReturnTable Select ltrim(rtrim(String.value('.', 'varchar(max)'))) FROM #XML.nodes('x') as T(String)
Return
End

Stored procedure throwing error on execution, I don't see the incorrect syntax where the error says

I have this stored procedure that I have written and when I go to execute it I keep getting an error...
Msg 102, Level 15, State 1, Procedure s_Add$Subject$Info, Line 127
Incorrect syntax near '#V'.
When I go to line 127 and look around, I can't see any incorrect syntax at the line or even in the area of it. Is there something I am not seeing? here is the stored procedure:
CREATE PROCEDURE s_Add$Subject$Info
(
#SubjectName varchar(50),
#SubjectDescription varchar(max),
#QuizIDString varchar(100),
#GamesIDString varchar(100),
#VideoIDString varchar(100)
)
as
--declare variables
declare #theSubID int
declare #quizIDLength int
declare #gamesIDLength int
declare #videoIDLength int
declare #quizIDs varchar(200)
declare #gamesIDs varchar(200)
declare #videoIDs varchar(200)
declare #numberCount int
declare #sTemp varchar(100)
--initializing variables
set #quizIDLength = LEN(#QuizIDString)
set #gamesIDLength = LEN(#GamesIDString)
set #videoIDLength = LEN(#VideoIDString)
set #quizIDs = ''
set #gamesIDs = ''
set #videoIDs = ''
set #numberCount = 1
--declare temp tables
declare #Q table --Quiz
(
QuizID varchar(100),
SubjectID int
)
declare #G table --Games
(
GamesID varchar(100),
SubjectID int
)
declare #V table --Videos
(
VideoID varchar(100),
SubjectID int
)
insert into[Subjects]
(SubjectName, SubjectDescription)
values
(#SubjectName, #SubjectDescription)
set #TheSubID = ##IDENTITY
--Check to see what strings are full then entering ids if true
--Quizzes first
if(#QuizIDLength > 0)
begin
while(#numberCount <=#quizIDLength)
begin
set #sTemp = SUBSTRING(#QuizIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #Q (QuizID, SubjectID) values (#quizIDs, #theSubID)
set #quizIDs = ''
end
if(#sTemp <> ',')
begin
set #quizIDs = #quizIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--Games second
if(#gamesIDLength > 0)
begin
while(#numberCount <=#gamesIDLength)
begin
set #sTemp = SUBSTRING(#GamesIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #G (GamesID, SubjectID) values (#gamesIDs, #theSubID)
set #gamesIDs = ''
end
if(#sTemp <> ',')
begin
set #gamesIDs = #gamesIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--Videos third
if(#videoIDLength > 0)
begin
while(#numberCount <=#videoIDLength)
begin
set #sTemp = SUBSTRING(#VideoIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #V (VideoID, SubjectID) values (#videoIDs, #theSubID)
set #videoIDs = ''
end
if(#sTemp <> ',')
begin
set #videoIDs = #videoIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--inserting the ids to subjectinfo table
insert into [SubjectInfo]
(SubjectID, QuizID)
select SubjectID, QuizID
from #Q
--Games
insert into [SubjectInfo]
(SubjectID, GameID)
select SubjectID, GameID
from #G
--Video
insert into [SubjectInfo]
(SubjectID, VideoID)
select SubjectID, VideoID
from #V
If you used better indentation formatting you'd easily be able to see that the problem is that you are missing some END statements:
CREATE PROCEDURE s_Add$Subject$Info
(
#SubjectName varchar(50),
#SubjectDescription varchar(max),
#QuizIDString varchar(100),
#GamesIDString varchar(100),
#VideoIDString varchar(100)
)
as
--declare variables
declare #theSubID int
declare #quizIDLength int
declare #gamesIDLength int
declare #videoIDLength int
declare #quizIDs varchar(200)
declare #gamesIDs varchar(200)
declare #videoIDs varchar(200)
declare #numberCount int
declare #sTemp varchar(100)
--initializing variables
set #quizIDLength = LEN(#QuizIDString)
set #gamesIDLength = LEN(#GamesIDString)
set #videoIDLength = LEN(#VideoIDString)
set #quizIDs = ''
set #gamesIDs = ''
set #videoIDs = ''
set #numberCount = 1
--declare temp tables
declare #Q table --Quiz
(
QuizID varchar(100),
SubjectID int
)
declare #G table --Games
(
GamesID varchar(100),
SubjectID int
)
declare #V table --Videos
(
VideoID varchar(100),
SubjectID int
)
insert into[Subjects]
(SubjectName, SubjectDescription)
values
(#SubjectName, #SubjectDescription)
set #TheSubID = ##IDENTITY
--Check to see what strings are full then entering ids if true
--Quizzes first
if(#QuizIDLength > 0)
begin
while(#numberCount <=#quizIDLength)
begin
set #sTemp = SUBSTRING(#QuizIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #Q (QuizID, SubjectID) values (#quizIDs, #theSubID)
set #quizIDs = ''
end
if(#sTemp <> ',')
begin
set #quizIDs = #quizIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--Games second
if(#gamesIDLength > 0)
begin
while(#numberCount <=#gamesIDLength)
begin
set #sTemp = SUBSTRING(#GamesIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #G (GamesID, SubjectID) values (#gamesIDs, #theSubID)
set #gamesIDs = ''
end
if(#sTemp <> ',')
begin
set #gamesIDs = #gamesIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--Videos third
if(#videoIDLength > 0)
begin
while(#numberCount <=#videoIDLength)
begin
set #sTemp = SUBSTRING(#VideoIDString, #numberCount, 1)
if(#sTemp = ',')
begin
insert #V (VideoID, SubjectID) values (#videoIDs, #theSubID)
set #videoIDs = ''
end
if(#sTemp <> ',')
begin
set #videoIDs = #videoIDs + #sTemp
end
set #numberCount = #numberCount + 1
end
--inserting the ids to subjectinfo table
insert into [SubjectInfo]
(SubjectID, QuizID)
select SubjectID, QuizID
from #Q
--Games
insert into [SubjectInfo]
(SubjectID, GameID)
select SubjectID, GameID
from #G
--Video
insert into [SubjectInfo]
(SubjectID, VideoID)
select SubjectID, VideoID
from #V
You missed the into keyword
insert #V (VideoID, SubjectID) values (#videoIDs, #theSubID)
^-------here

Converting String List into Int List in SQL

I have a nvarchar(MAX) in my stored procedure which contains the list of int values, I did it like this as it is not possible to pass int list to my stored procedure,
but, now I am getting problem as my datatype is int and I want to compare the list of string.
Is there a way around by which I can do the same?
---myquerry----where status in (#statuslist)
but the statuslist contains now string values not int, so how to convert them into INT?
UPDate:
USE [Database]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[SP]
(
#FromDate datetime = 0,
#ToDate datetime = 0,
#ID int=0,
#List nvarchar(MAX) //This is the List which has string ids//
)
AS
SET FMTONLY OFF;
DECLARE #sql nvarchar(MAX),
#paramlist nvarchar(MAX)
SET #sql = 'SELECT ------ and Code in(#xList)
and -------------'
SELECT #paramlist = '#xFromDate datetime,#xToDate datetime,#xId int,#xList nvarchar(MAX)'
EXEC sp_executesql #sql, #paramlist,
#xFromDate = #FromDate ,#xToDate=#ToDate,#xId=#ID,#xList=#List
PRINT #sql
So when I implement that function that splits then I am not able to specify the charcter or delimiter as it is not accepting it as (#List,',').
or (','+#List+',').
It is possible to send an int list to your stored procedure using XML parameters. This way you don't have to tackle this problem anymore and it is a better and more clean solution.
have a look at this question:
Passing an array of parameters to a stored procedure
or check this code project:
http://www.codeproject.com/Articles/20847/Passing-Arrays-in-SQL-Parameters-using-XML-Data-Ty
However if you insist on doing it your way you could use this function:
CREATE FUNCTION [dbo].[fnStringList2Table]
(
#List varchar(MAX)
)
RETURNS
#ParsedList table
(
item int
)
AS
BEGIN
DECLARE #item varchar(800), #Pos int
SET #List = LTRIM(RTRIM(#List))+ ','
SET #Pos = CHARINDEX(',', #List, 1)
WHILE #Pos > 0
BEGIN
SET #item = LTRIM(RTRIM(LEFT(#List, #Pos - 1)))
IF #item <> ''
BEGIN
INSERT INTO #ParsedList (item)
VALUES (CAST(#item AS int))
END
SET #List = RIGHT(#List, LEN(#List) - #Pos)
SET #Pos = CHARINDEX(',', #List, 1)
END
RETURN
END
Call it like this:
SELECT *
FROM Table
WHERE status IN (SELECT * from fnStringList2Table(#statuslist))
You can work with string list too. I always do.
declare #statuslist nvarchar(max)
set #statuslist = '1, 2, 3, 4'
declare #sql nvarchar(max)
set #sql = 'select * from table where Status in (' + #statuslist + ')'
Execute(#sql)
You can do this by using sql function which will return you an integer array..
It would be great if you pass #Delimiter separated string to your stored procedure which could be processed properly afterwards.
Write one function to split the data as following
CREATE FUNCTION [dbo].[SplitValues] (#StringArray NVARCHAR(MAX), #Delimiter NVARCHAR(10))
RETURNS #ResultedValues table
(
ResultValue INT
)
AS
BEGIN
DECLARE #Tokens TABLE(Token nvarchar)
DECLARE #String nvarchar
WHILE (CHARINDEX(#Delimiter,#StringArray)>0)
BEGIN
INSERT INTO #Tokens (Token) VALUES (LTRIM(RTRIM(SUBSTRING(#StringArray,1,CHARINDEX(#Delimiter,#StringArray)-1))))
SET #String = SUBSTRING(#StringArray,
CHARINDEX(#Delimiter,#StringArray)+LEN(#Delimiter),LEN(#StringArray))
END
INSERT INTO #ResultedValues (ResultValue ) VALUES ( CAST(LTRIM(RTRIM(#String)) AS INT))
RETURN
END
And then use it like following, i am using (,) as #Delimiter here
SELECT ResultValue [YourSchema].[SplitValues](#statuslist,',')
Actually, you can send the list of int values to your procedure by creating a User Defined Table Type. However, this implies more work in order to populate the table parameter.
In your case, you can use the sp_executesql stored procedure to achieve what you want like this:
declare #statement nvarchar(4000) = '----your query---- where status in ('
+ #statusList +')'
sp_executesql #statement
here is an example of how to do it and the Link for more informations
ALTER FUNCTION iter_intlist_to_tbl (#list nvarchar(MAX))
RETURNS #tbl TABLE (listpos int IDENTITY(1, 1) NOT NULL,
number int NOT NULL) AS
BEGIN
DECLARE #startpos int,
#endpos int,
#textpos int,
#chunklen smallint,
#str nvarchar(4000),
#tmpstr nvarchar(4000),
#leftover nvarchar(4000)
SET #textpos = 1
SET #leftover = ''
WHILE #textpos <= datalength(#list) / 2
BEGIN
SET #chunklen = 4000 - datalength(#leftover) / 2
SET #tmpstr = ltrim(#leftover + substring(#list, #textpos, #chunklen))
SET #textpos = #textpos + #chunklen
SET #startpos = 0
SET #endpos = charindex(' ' COLLATE Slovenian_BIN2, #tmpstr)
WHILE #endpos > 0
BEGIN
SET #str = substring(#tmpstr, #startpos + 1, #endpos - #startpos - 1)
IF #str <> ''
INSERT #tbl (number) VALUES(convert(int, #str))
SET #startpos = #endpos
SET #endpos = charindex(' ' COLLATE Slovenian_BIN2, #tmpstr, #startpos + 1)
END
SET #leftover = right(#tmpstr, datalength(#tmpstr) / 2 - #startpos)
END
IF ltrim(rtrim(#leftover)) <> ''
INSERT #tbl (number) VALUES(convert(int, #leftover))
RETURN
END
-- ############################ Example ############################
--CREATE PROCEDURE get_product_names_iter #ids varchar(50) AS
--SELECT P.ProductName, P.ProductID
--FROM Northwind..Products P
--JOIN iter_intlist_to_tbl(#ids) i ON P.ProductID = i.number
--go
--EXEC get_product_names_iter '9 12 27 37'
-- ############################ WICHTIG ############################
This works for me on an Informix DataBase:
DROP FUNCTION rrhh:fnc_StringList_To_Table;
CREATE FUNCTION rrhh:fnc_StringList_To_Table (pStringList varchar(250))
RETURNING INT as NUMERO;
/* A esta Funcion le podes pasar una cadena CSV con una lista de numeros
* Ejem: EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
* y te devolvera una Tabla con dichos numeros separados uno x fila
* Autor: Jhollman Chacon #Cutcsa - 2019 */
DEFINE _STRING VARCHAR(255);
DEFINE _LEN INT;
DEFINE _POS INT;
DEFINE _START INT;
DEFINE _CHAR VARCHAR(1);
DEFINE _VAL INT;
LET _STRING = REPLACE(pStringList, ' ', '');
LET _START = 0;
LET _POS = 0;
LET _LEN = LENGTH(_STRING);
FOR _POS = _START TO _LEN
LET _CHAR = SUBSTRING(pStringList FROM _POS FOR 1);
IF _CHAR <> ',' THEN
LET _VAL = _CHAR::INT;
ELSE
LET _VAL = NULL;
END IF;
IF _VAL IS NOT NULL THEN
RETURN _VAL WITH RESUME;
END IF;
END FOR;
END FUNCTION;
EXECUTE FUNCTION fnc_StringList_To_Table('1,2,3,4');
SELECT * FROM TABLE (fnc_StringList_To_Table('1,2,3,4'));

Looking for multiples substrings within a SQL string

I have several occurrences of differences strings in the columns, like this example
'dsasdasdsd'+'ewewewew'+'45454545'+(avg('uuuuuuu'))
I need to split this string into several columns with the substrings that are between
aphostropes
like this:
Column 1 = dsasdasdsd
Column 2 = ewewewew
Column 3 = 45454545
Column 4 = uuuuuuu
The numbers of apperances are random, thefore the length of the original column is also not fixed (from 50 char to > 1000)
DECLARE #InStr VarChar(1000) = '''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))'''
DECLARE #intStart INT = 0
DECLARE #intEnd INT = 1
DECLARE #ColNo INT = 1
DECLARE #MyString VARCHAR(2000)
DECLARE #SelectString VARCHAR(8000) = 'SELECT '
WHILE(#intStart < LEN(#InStr) )
BEGIN
SELECT #intStart = CHARINDEX(CHAR(39), #InStr, 0) + 1
SELECT #intEnd = CHARINDEX(CHAR(39), #InStr, #intStart)
SELECT #SelectString = #SelectString + CHAR(39) + SUBSTRING(#InStr, #intStart, #intEnd - #intStart) + CHAR(39) + ' As [Column ' + CAST(#ColNo As Varchar) + '],'
SELECT #InStr = SUBSTRING(#InStr, #intEnd + 1, LEN(#InStr)-#intEnd )
SET #ColNo = #ColNo +1
END
SELECT #SelectString = LEFT(#SelectString, Len(#SelectString) -1)
EXEC (#SelectString)
I have been playing with this and this does run but unfortunately I don't have time right now to carry on with it but maybe you can improve on this?
HTH
You can try this:
create table tSqlStrings (sText nvarchar(1000))
insert tSqlStrings values('''dsasdasdsd''+''ewewewew''+''45454545''+(avg(''uuuuuuu''))')
create table tResults (
sColumn1 nvarchar(1000)
,sColumn2 nvarchar(1000)
,sColumn3 nvarchar(1000)
,sColumn4 nvarchar(1000)
)
and
DELETE tResults
DECLARE #sText nvarchar(1000) = (
SELECT
sText
FROM
tSqlStrings
)
DECLARE #lBegin int = CHARINDEX('''',#sText)
DECLARE #lEnd int = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
DECLARE #sText0 nvarchar(1000)
DECLARE #sColumn1 nvarchar(1000)
DECLARE #sColumn2 nvarchar(1000)
DECLARE #sColumn3 nvarchar(1000)
DECLARE #sColumn4 nvarchar(1000)
DECLARE #iCnt int = 1
while #iCnt<=4
--(0<len(#sText) and 0<#lBegin and 0<#lEnd)
BEGIN
SET #sText0 = substring(#sText,#lBegin+1,#lEnd-2)
IF #iCnt=1 begin SET #sColumn1=#sText0 end
IF #iCnt=2 begin SET #sColumn2=#sText0 end
IF #iCnt=3 begin SET #sColumn3=#sText0 end
IF #iCnt=4 begin SET #sColumn4=#sText0 end
set #sText = substring(#sText,#lBegin + #lEnd+2,len(#sText))
SET #lBegin = CHARINDEX('''',#sText)
SET #lEnd = charindex('''',
substring(#sText,
CHARINDEX('''',#sText)+1,
len(#sText)))
SET #iCnt = #iCnt+1
END
INSERT
tResults (sColumn1,sColumn2,sColumn3,sColumn4)
VALUES (#sColumn1,#sColumn2,#sColumn3,#sColumn4)
SELECT * FROM tResults
on sql fiddle
You will be able to achieve this using CHARINDEX() and SUBSTRING()
Following example shows for splitting to 2 columns. When it has more columns, query will be get little more complicated. However, you can follow this to build your query.
SELECT OriginalColumn
, SUBSTRING(OriginalColumn, 1,CHARINDEX('x',OriginalColumn,1)-1) AS Column1
, SUBSTRING(OriginalColumn, CHARINDEX('x',OriginalColumn,1) + 1 ,CHARINDEX('x',OriginalColumn,CHARINDEX('x',OriginalColumn,1)-1)) AS Column2
FROM YourTable
I have used "x" as the delimiter in the example. Following is a sample result
try this:
declare #delim char
set #delim = ''''
declare #str nvarchar(max)
declare #substr nvarchar(max)
declare #newstr nvarchar(max)
declare #tmpTable table (partStrings nvarchar(max))
declare #count int
set #count = 0
select #str = <***Your String***>
while(charindex(#delim,#str) != 0)
begin
set #count = #count + 1
Select #substr = substring(#str,1,charindex(#delim,#str)-1)
if((#count % 2) = 0)
begin
insert into #tmpTable values(#substr)
end
Set #newstr = substring(#str,charindex(#delim,#str)+1,len(#str)-charindex(#delim,#str))
set #str = #newstr
end
select partStrings from #tmpTable