I am running SQL Server 2008. in a stored procedure, I need to copy TableA to TableB by making a comma-delimted string from a subset of columns in TableA and write it along with some other data to TableB.
TableA contains 12 text columns named 'Column1' thru 'Column12'.
For each row in TableA I need a comma-separated string built from a variable range of columns defined by parameters #startCol and #endCol passed to the stored procedure. I need to copy #startCol and #endCol plus the string to another table.
TableB:
StartCol, EndCol, CommaDelim
This is what I'm trying:
INSERT INTO TableB SELECT #startCol as StartCol, #endCol As EndCol,
COALESCE(???) as CommaDelim
I can't figure out what to pass to the COALESCE function. I'm not even sure I should be using COALESCE. I'm not averse to dynamic SQL
TableA:
Column1 Column2 Column3 ….
'A1' 'A2' 'A3'
'B1' 'B2' 'B3'
.
.
.
what I want in TableB is
StartCol EndCol CommaDelim
1 3 'A1,A2,A3'
1 3 'B1,B2,B3'
one record for each record in TableA
I can't get any result set - I keep getting syntax errors in the COALESCE part
Perhaps a little over-developed, but here is a technique that does NOT require dynamic SQL
Notice I set Columns between 1 & 2, but you can set any range
Example
Declare #YourTable Table ([Column1] varchar(50),[Column2] varchar(50),[Column3] varchar(50))
Insert Into #YourTable Values
('A1','A2','A3')
,('B1','B2','B3')
Declare #Col1 int = 1
Declare #Col2 int = 2
Select StartCol = #Col1
,EndCol = #Col2
,C.*
From #YourTable A
Cross Apply ( values (cast((Select A.* for XML RAW,ELEMENTS XSINIL) as xml))) B(XMLData)
Cross Apply ( values (stuff((Select ',' + Value
From (
Select Seq = row_number() over (order by (select null))
,Item = a.value('local-name(.)','varchar(100)')
,Value = a.value('.','varchar(max)')
From B.XMLData.nodes('/row') as C1(n)
Cross Apply C1.n.nodes('./*') as C2(a)
) B1
Where Seq between #Col1 and #Col2
Order By Seq
For XML Path (''))
,1,1,'')
)
) C(CommaDelim)
Returns
StartCol EndCol CommaDelim
1 2 A1,A2
1 2 B1,B2
You will have to convert them into VARCHAR datatype so that you can concatenate them. COALESCE is picking the first null column in the list.
Example:
ISNULL(CONVERT(VARCHAR(Length),Column1),'')+','+ISNULL(CONVERT(VARCHAR(Length),Column2),'')+','+ISNULL(CONVERT(VARCHAR(Length),Column3),'')
Hope that helps!
I came up with a way so that you do not have to create dynamic sql by creating a function. You may have to modify the select statements to match your schema. You can use the function this way:
select dbo.getString(#startCol, #endCol)
create function getString(#startCol int, #endCol int)
returns varchar(40)
as
begin
declare #str varchar(40) = ""
declare #i int = #startCol
if #endCol < #startCol
begin
return #str
end
while #i < #endCol + 1
begin
if #i = 1
begin
select #str = #str + Column1 + ","
from TableA
end
if #i = 2
begin
select #str = #str + Column2 + ","
from TableA
end
if #i = 3
begin
select #str = #str + Column3 + ","
from TableA
end
if #i = 4
begin
select #str = #str + Column4 + ","
from TableA
end
if #i = 5
begin
select #str = #str + Column5 + ","
from TableA
end
if #i = 6
begin
select #str = #str + Column6 + ","
from TableA
end
if #i = 7
begin
select #str = #str + Column7 + ","
from TableA
end
if #i = 8
begin
select #str = #str + Column8 + ","
from TableA
end
if #i = 9
begin
select #str = #str + Column9 + ","
from TableA
end
if #i = 10
begin
select #str = #str + Column10 + ","
from TableA
end
if #i = 11
begin
select #str = #str + Column11 + ","
from TableA
end
if #i = 12
begin
select #str = #str + Column12 + ","
from TableA
end
set #i = #i + 1
end
set #str = substring(#str, 1, len(#str) - 1)
return #str
end
Related
I have a bunch of strings that should have been stored as value pairs but were not. Now I need to replace every other comma with a semicolon to make them pairs. Hoping to find a simple way of doing this, but there might not be one.
ex:
-1328.89,6354.22,-1283.94,6242.96,-1172.68,6287.91,-1217.63,6399.18
should be:
-1328.89,6354.22;-1283.94,6242.96;-1172.68,6287.91;-1217.63,6399.18
create function f_tst(#a varchar(100)) -- use right size of field
returns varchar(100) -- make sure you use the right size of field
begin
declare #pos int = charindex(',', #a) + 1
;while 0 < charindex(',', #a, #pos)
select #a = stuff(#a, charindex(',', #a, #pos), 1, ';'),
#pos = charindex(',', #a, charindex(',', #a, #pos + 1)) + 1
return #a
end
go
declare #a varchar(100) = '-1328.89,6354.22,-1283.94,6242.96,-1172.68,6287.91,-1217.63,6399.18'
select dbo.f_tst(#a)
Or in your example
update <table>
set <field> = dbo.f_tst(<field>)
Surely not so simple as you want, but a CHARINDEX/SUBSTRING solution:
Declare #input nvarchar(max) = '-1328.89,6354.22,-1283.94,6242.96,-1172.68,6287.91,-1217.63,6399.18'
Declare #i int = 0, #t int = 0, #isComma bit = 1
Declare #output nvarchar(max) = ''
Select #i = CHARINDEX(',', #input)
While (#i > 0)
Begin
Select #output = #output + SUBSTRING(#input, #t + 1, #i - #t - 1) + CASE #isComma WHEN 1 THEN ',' ELSE ';' END
Select #t = #i
Select #i = CHARINDEX(',', #input, #i + 1), #isComma = 1 - #isComma
End
Select #output = #output + SUBSTRING(#input, #t + 1, 1000)
Select #output
This can be done with a combination of dynamic sql and for xml:
declare #sql nvarchar(max)
set #sql = '-1328.89,6354.22,-1283.94,6242.96,-1172.68,6287.91,-1217.63,6399.18'
set #sql = '
select replace((select cast(value as varchar(50)) +
cast(case row_number() over(order by sort)%2 when 0 then '','' else '';'' end as char(1))
from (select ' + replace(#sql,',',' value,1 sort union all select ') + ',1 sort)q
for xml path(''''))+''||'','',||'','''') YourUpdatedValue'
exec(#sql)
This can be done in a single query:
DECLARE #t TABLE (id int, col varchar(max))
INSERT #t VALUES
(1,'-1328.89,6354.22,-1283.94,6242.96,-1172.68,6287.91,-1217.63,6399.18'),
(2,'-4534.89,454.22,-1123.94,2932.96,-1872.68,327.91,-417.63,635.18')
;WITH t AS (
SELECT id, i % 2 x, i / 2 y, val
FROM #t
CROSS APPLY (SELECT CAST('<a>'+REPLACE(col,',','</a><a>')+'</a>' AS xml) xml1 ) t1
CROSS APPLY (
SELECT
n.value('for $i in . return count(../*[. << $i])', 'int') i,
n.value('.','varchar(max)') AS val
FROM xml1.nodes('a') x(n)
) t2
)
SELECT id, y, [0]+','+[1] col
FROM t
PIVOT(MAX([val]) FOR x IN ([0],[1])) t3
ORDER BY id, y
id y val
----------------------------
1 0 -1328.89,6354.22
1 1 -1283.94,6242.96
1 2 -1172.68,6287.91
1 3 -1217.63,6399.18
2 0 -4534.89,454.22
2 1 -1123.94,2932.96
2 2 -1872.68,327.91
2 3 -417.63,635.18
I want split text from NAME column and insert comma separated data to PARCA column for each row. ex:
name parca
---- -------------
john j,jo,joh,john
Code:
DECLARE #i int = 0
WHILE #i < 8
BEGIN
SET #i = #i + 1
update export1 set PARCA = cast ( PARCA as nvarchar(max)) + cast (substring(NAME,1,#i) as nvarchar(max) ) +','
FROM export1
end
There are two things I can't do;
I could not equalize the #i value to name row count
I could not checked NAME column whether the value in PARCA column
Create this function:
create function f_parca
(
#name varchar(100)
) returns varchar(max)
as
begin
declare #rv varchar(max) = ''
if #name is not null
select top (len(#name)) #rv += ','+ left(#name, number + 1)
from master..spt_values v
where type = 'p'
return stuff(#rv, 1,1,'')
end
Testing the function
select dbo.f_parca('TClausen')
Result:
T,TC,TCl,TCla,TClau,TClaus,TClause,TClausen
Update your table like this:
UPDATE export1
SET PARCA = dbo.f_parca(name)
DECLARE #Count INT,#I INT
SET #I = 1
SET #Count = LEN('SURESH')
DECLARE #N VARCHAR(2000)
SET #N = ''
WHILE #Count > 0
BEGIN
SET #N = #N + ','+SUBSTRING('SURESH',1,#I)
SET #I = #I+1
SET #Count = #Count -1
END
SELECT SUBSTRING(#N,2,2000)
The above code is only a sample.'SURESH' is your name field.from which you can pass your own name values.Instead of final select u can put ur update.
Try this, this query will break the word into characters rows as expected then you can merge into a single row
DECLARE #Name AS Varchar(100)='Naveen'
;with cte as
(
select 1 AS Counter,CAST(SUBSTRING(#Name, 1, 1) AS Varchar(100)) Name
union all
select Counter+1,CAST((Name + ',' + SUBSTRING(#Name, Counter+1, 1))AS Varchar(100)) Name
from cte
where Len(Name) < Len(#Name) + (Len(#Name) -1)
)
select
Name
from cte
option(MAXRECURSION 0)
-- This query will give you exactly what you are looking for, use Emp Table with Ename as column
;with cte as
(
select 1 AS Counter,EName,CAST(SUBSTRING(E.EName, 1, 1) AS Varchar(100)) Name
From EMP E
union all
select Counter+1,E.EName,CAST((Name + SUBSTRING(E.EName, Counter+1, 1))AS Varchar(100)) Name
From EMP E
INNER JOIN CTE C ON C.Ename=E.EName
where Len(Name) < Len(E.EName)
)
select EName AS Name,
STUFF(( SELECT ',' + Name AS [text()]
FROM CTE A
WHERE
A.EName = cte.EName
FOR XML PATH('')
), 1, 1, '' )
AS Parca
from cte
Group By EName
Order By EName
option(MAXRECURSION 0)
I have two variables like:
#FieldName
#values
Those two variables hold values like:
#FieldName - contains [a],[b],[c],[d]
#values - contains 5,6,7,8
Now I need to retrieve the data of column 'b' & 'd' only.
How can we get b=6 & d=8?
Thanks in advance.
well I hate to do such a things on SQL Server, but
declare #FieldName nvarchar(max) = '[a],[b],[c],[d]'
declare #values nvarchar(max) = '5,6,7,8'
declare #i int, #j int, #break int
declare #a nvarchar(max), #b nvarchar(max), #result nvarchar(max)
select #break = 0
while #break = 0
begin
select #i = charindex(',', #FieldName), #j = charindex(',', #values)
if #i > 0 and #j > 0
begin
select #a = left(#FieldName, #i - 1), #b = left(#values, #j - 1)
select #FieldName = right(#FieldName, len(#FieldName) - #i), #values = right(#values, len(#values) - #j)
end
else
begin
select #a = #FieldName, #b = #values, #break = 1
end
if #a in ('[b]', '[d]')
select #result = isnull(#result + ' & ', '') + #a + '=' + #b
end
select #result
You can also put all this list into temporary/variable table and do join.
select *
from
(
select T.<yourcolumn>, row_number() over (order by T.<yourcolumn>) as rownum
from <temptable1> as T
) as F
inner join
(
select T.<yourcolumn>, row_number() over (order by T.<yourcolumn>) as rownum
from <temptable2> as T
) as V on V.rownum = F.rownum
Or, even better, you can pass parameters into sp in xml form and not in distinct lists
Try this :
Using XML i'm are trying to spilt the values and storing the result in a table variable
DECLARE #FieldName VARCHAR(MAX),
#values varchar(max)
SET #FieldName = 'a,b,c,d';
SET #values = '5,6,7,8'
SET #FieldName = #FieldName + ',';
SET #values = #values + ',';
DECLARE #X XML
SET #X = CAST('<Item>' + REPLACE(#FieldName, ',', '</Item><Item>') + '</Item>' AS XML)
Declare #X1 XML
Set #X1=CAST('<Position>' + REPLACE(#values, ',', '</Position><Position>') + '</Position>' AS XML)
Declare #FieldSample table
(
FieldName char(1),
rowNum int
)
Declare #valueSample table
(position int,
rowNum int)
Insert into #FieldSample(rowNum,FieldName)
Select * from (
SELECT row_number() over (order by (select 0)) as rowNum, t.value('.', 'char(1)') as field
FROM #x.nodes('/Item') as x(t)
) as a
where a.field !=''
Insert into #valueSample(rowNum,position)
Select * from (
Select row_number() over (order by (select 0)) as rowNum, k.value('.', 'int') as position
from #X1.nodes('/Position') as x1(k)
) as b
where b.position !=0
Basically the last logic you can change it based on how you intend to get the data
Select a.FieldName,b.position from #FieldSample as a
inner join #valueSample as b
on a.rowNum=b.rowNum
where b.position = 6 or b.position =8
My table has one column that contain strings like: ” HRM_APPLICATION_DELAY_IN”
I want to perform bellow operations on each row on this column
convert to lower case
remove underscore “_”
change case (convert to upper case) of the character after the underscore like: ” hrm_Application_Delay_In”
Need help for conversion. Thanks for advance
Here is a function to achieve it:
create function f_test
(
#a varchar(max)
)
returns varchar(max)
as
begin
set #a = lower(#a)
while #a LIKE '%\_%' ESCAPE '\'
begin
select #a = stuff(#a, v, 2, upper(substring(#a, v+1,1)))
from (select charindex('_', #a) v) a
end
return #a
end
Example:
select dbo.f_test( HRM_APPLICATION_DELAY_IN')
Result:
hrmApplicationDelayIn
To update your table here is an example how to write the syntax with the function:
UPDATE <yourtable>
SET <yourcolumn> = dbo.f_test(col)
WHERE <yourcolumn> LIKE '%\_%' ESCAPE '\'
For a variable this is overkill, but I'm using this to demonstrate a pattern
declare #str varchar(100) = 'HRM_APPLICATION_DELAY_IN';
;with c(one,last,rest) as (
select cast(lower(left(#str,1)) as varchar(max)),
left(#str,1), stuff(lower(#str),1,1,'')
union all
select one+case when last='_'
then upper(left(rest,1))
else left(rest,1) end,
left(rest,1), stuff(rest,1,1,'')
from c
where rest > ''
)
select max(one)
from c;
That can be extended to a column in a table
-- Sample table
declare #tbl table (
id int identity not null primary key clustered,
str varchar(100)
);
insert #tbl values
('HRM_APPLICATION_DELAY_IN'),
('HRM_APPLICATION_DELAY_OUT'),
('_HRM_APPLICATION_DELAY_OUT'),
(''),
(null),
('abc<de_fg>hi');
-- the query
;with c(id,one,last,rest) as (
select id,cast(lower(left(str,1)) as varchar(max)),
left(str,1), stuff(lower(str),1,1,'')
from #tbl
union all
select id,one+case when last='_'
then upper(left(rest,1))
else left(rest,1) end,
left(rest,1), stuff(rest,1,1,'')
from c
where rest > ''
)
select id,max(one)
from c
group by id
option (maxrecursion 0);
-- result
ID COLUMN_1
1 hrm_Application_Delay_In
2 hrm_Application_Delay_Out
3 _Hrm_Application_Delay_Out
4
5 (null)
6 abc<de_Fg>hi
select
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(replace(
replace(replace(replace(replace(replace(replace(lower('HRM_APPLICATION_DELAY_IN'),'_a','A'),'_b','B'),'_c','C'),'_d','D'),'_e','E'),'_f','F'),
'_g','G'),'_h','H'),'_i','I'),'_j','J'),'_k','K'),'_l','L'),
'_m','M'),'_n','N'),'_o','O'),'_p','P'),'_q','Q'),'_r','R'),
'_s','S'),'_t','T'),'_u','U'),'_v','V'),'_w','W'),'_x','X'),
'_y','Y'),'_z','Z'),'_','')
Bellow two steps can solve problem,as example i use sys.table.user can use any one
declare #Ret varchar(8000), #RetVal varchar(8000), #i int, #count int = 1;
declare #c varchar(10), #Text varchar(8000), #PrevCase varchar, #ModPrefix varchar(10);
DECLARE #FileDataTable TABLE(TableName varchar(200))
INSERT INTO #FileDataTable
select name FROM sys.tables where object_name(object_id) not like 'sys%' order by name
SET #ModPrefix = 'Pur'
DECLARE crsTablesTruncIns CURSOR
FOR select TableName FROM #FileDataTable
OPEN crsTablesTruncIns
FETCH NEXT FROM crsTablesTruncIns INTO #Text
WHILE ##FETCH_STATUS = 0
BEGIN
SET #RetVal = '';
select #i=1, #Ret = '';
while (#i <= len(#Text))
begin
SET #c = substring(#Text,#i,1)
--SET #Ret = #Ret + case when #Reset=1 then UPPER(#c) else LOWER(#c)
IF(#PrevCase = '_' OR #i = 1)
SET #Ret = UPPER(#c)
ELSE
SET #Ret = LOWER(#c)
--#Reset = case when #c like '[a-zA-Z]' then 0 else 1 end,
if(#c like '[a-zA-Z]')
SET #RetVal = #RetVal + #Ret
if(#c = '_')
SET #PrevCase = '_'
else
SET #PrevCase = ''
SET #i = #i +1
end
SET #RetVal = #ModPrefix + #RetVal
print cast(#count as varchar) + ' ' + #RetVal
SET #count = #count + 1
EXEC sp_RENAME #Text , #RetVal
SET #RetVal = ''
FETCH NEXT FROM crsTablesTruncIns INTO #Text
END
CLOSE crsTablesTruncIns
DEALLOCATE crsTablesTruncIns
I'd like to show you my nice and simple solution. It uses Tally function to split the string by pattern, in our case by underscope. For understanding Tally functions, read this article.
So, this is how my tally function looks like:
CREATE FUNCTION [dbo].[tvf_xt_tally_split](
#String NVARCHAR(max)
,#Delim CHAR(1))
RETURNS TABLE
as
return
(
WITH Tally AS (SELECT top (select isnull(LEN(#String),100)) n = ROW_NUMBER() OVER(ORDER BY [name]) from master.dbo.syscolumns)
(
SELECT LTRIM(RTRIM(SUBSTRING(#Delim + #String + #Delim,N+1,CHARINDEX(#Delim,#Delim + #String + #Delim,N+1)-N-1))) Value, N as Ix
FROM Tally
WHERE N < LEN(#Delim + #String + #Delim)
AND SUBSTRING(#Delim + #String + #Delim,N,1) = #Delim
)
)
This function returns a table, where each row represents part of string between #Delim (in our case between underscopes). Rest of the work is simple, just cobination of LEFT, RIGHT, LEN, UPPER and LOWER functions.
declare #string varchar(max)
set #string = ' HRM_APPLICATION_DELAY_IN'
-- convert to lower case
set #string = LOWER(#string)
declare #output varchar(max)
-- build string
select #output = coalesce(#output + '_','') +
UPPER(left(Value,1)) + RIGHT(Value, LEN(Value) - 1)
from dbo.tvf_xt_tally_split(#string, '_')
-- lower first char
select left(lower(#output),1) + RIGHT(#output, LEN(#output) - 1)
COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C
I want to seperate the above string as (Required Output)
col1 col2 col3 col4 col5 col6
COMMSTR1 NAC-NAM-P-C FCPANAM1 NAC-NAM-P-C CHAZEL1 NAT-CBM-P-C
I've tried this.
SELECT Contact_assg_list_src,
Contact_Assg_List_Src =
(
case WHEN Contact_Assg_List_Src IS NOT NULL and Contact_Assg_List_Src <> ''
then left(Contact_Assg_List_Src,patindex('%[-]%',Contact_Assg_List_Src)-1)
ELSE Contact_Assg_List_Src
END),
(case WHEN Contact_Assg_List_Src IS NOT NULL and Contact_Assg_List_Src <> ''
then substring(Contact_Assg_List_Src,(Patindex('%[-]%',Contact_Assg_List_Src + ' ')-1),len(Contact_Assg_List_Src))
ELSE Contact_Assg_List_Src
END)
from dbo.FBMSRAW;
Which gives me output like
col1 col2
COMMSTR1 NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C
How can I check whether the string has space then separate the string based on that to
get required output?
If you want to do it efficiently in SQL server, I'd advise using a CLR function.
But if you have to do it in T-SQL, this function will achieve it (slowly, and in an increasingly inefficient way)
create function SplitString
(
#splitchar char(1),
#string varchar(500),
#index int
)
returns varchar(500)
as
begin
declare #split int, #start int, #loop bit, #i int, #ret varchar(500)
select #start = 0, #i = 0
select #split = charindex(#splitchar, #string, 0)
if #index>0
select #loop = 1
else
select #loop = 0
while #loop = 1
begin
select #start = #split+1
select #split = charindex(#splitchar, #string, #start+1)
if #split = 0
begin
select #split = len(#string)+1
end
select #i = #i + 1
if #i = #index
begin
select #loop = 0
end
end
if #split>#start
select #ret = substring(#string, #start, #split-#start)
else
select #ret = null
return #ret
end
select dbo.SplitString (' ', 'COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C', [0 based column number])
I have wrote the following script to suit your needs, but your self you need to add some more logic, understand the following script
Create a dummy table
CREATE TABLE TBL_TEMPSTRINGS(STRCOL VARCHAR(200),COL1 VARCHAR(50),
COL2 VARCHAR(50),COL3 VARCHAR(50))
Insert values from your table
INSERT INTO TBL_TEMPSTRINGS
SELECT Contact_assg_list_src From dbo.FBMSRAW
Create a stored procedure to update your dummy table columns, it takes your table name in a string(why you can replace your dummy table with temp table name if you have used)
CREATE PROC SP_SPLITWRODS(#TABLENAME VARCHAR(50),#COLCOUNT INT)
AS
BEGIN
DECLARE #QRY VARCHAR(500)
CREATE TABLE #TBL_TEMP(STRCOL VARCHAR(200))
DECLARE #STRCOL VARCHAR(200)
DECLARE #CURRINDEX INT
DECLARE #TEMP INT
DECLARE #COLINDEX INT
DECLARE #ROWID INT
DECLARE #STRLEN INT
DECLARE #TEMPVALUE VARCHAR(50)
DECLARE #LASTWORD BIT
--CURSOR FOR YOUR TEMP TABLE
DECLARE CUR_TEMP CURSOR LOCAL FOR SELECT STRCOL FROM #TBL_TEMP
--CONSTRUCT QRY FOR FILLING YOUR TABLE
SET #QRY='INSERT INTO #TBL_TEMP SELECT STRCOL FROM ' + #TABLENAME
--FILL TABLE
EXECUTE(#QRY)
OPEN CUR_TEMP
FETCH CUR_TEMP INTO #STRCOL
WHILE ##FETCH_STATUS = 0
BEGIN
SET #CURRINDEX=1
SET #COLINDEX=1
SET #LASTWORD=0
--GET ' ' INDEX
SET #TEMP=CHARINDEX(' ',#STRCOL,#CURRINDEX)
WHILE #TEMP > 0
BEGIN
--YOU WILL GET THE VALUE SEPERATED BY SPACE
SET #TEMPVALUE=SUBSTRING(#STRCOL,#CURRINDEX,#TEMP-#CURRINDEX)
--ADD MORE LOGIC TO UPDATE YOUR COLUMNS (YOUR EXTRA COLUMNS)
--CONTRUCT QRY TO UPDATE CORRESPONDING COL IN YOUR TABLE FOR THE ROW FETCHED
--THIS UPDATES ALL ROWS, YOU NEED TO ADD ONE WHERE CONDITION TO UPDATE THE ROW
SET #QRY='UPDATE ' + #TABLENAME + ' SET COL' + CAST(#COLINDEX AS VARCHAR) + '=''' + #TEMPVALUE + ''''
EXEC(#QRY)
--INCREMENT COL INDEX AFTER UPDATE OF LAST COLUMN
SET #COLINDEX=#COLINDEX+1
SET #CURRINDEX=#TEMP+1
SET #TEMP=CHARINDEX(' ',#STRCOL,#CURRINDEX)
IF #TEMP=0 AND #LASTWORD=0
BEGIN
SET #TEMP=LEN(#STRCOL)+1
SET #LASTWORD=1
END
END
FETCH CUR_TEMP INTO #STRCOL
END
CLOSE CUR_TEMP
DEALLOCATE CUR_TEMP
END
Execute your proc
EXEC SP_SPLITWRODS 'TBL_TEMPSTRINGS',1
See your updated dummy table
SELECT * FROM TBL_TEMPSTRINGS
Presently it is updates 3 columns split by the space, you need to add your own logic to update the columns based on the string you have received(seperated by space).
Hope it helps
First a function to split the text
create function [dbo].[f_split]
(
#param nvarchar(max),
#delimiter char(1)
)
returns #t table (val nvarchar(max), seq int)
as
begin
set #param += #delimiter
;with a as
(
select cast(1 as bigint) f, charindex(#delimiter, #param) t, 1 seq
union all
select t + 1, charindex(#delimiter, #param, t + 1), seq + 1
from a
where charindex(#delimiter, #param, t + 1) > 0
)
insert #t
select substring(#param, f, t - f), seq from a
option (maxrecursion 0)
return
end
go
Query to display the result, assuming there are max 6 'words'
declare #t table(txt nvarchar(500))
insert #t values ('COMMSTR1-NAC-NAM-P-C FCPANAM1-NAC-NAM-P-C CHAZEL1-NAT-CBM-P-C'),
('t1 t2 t3 t4 t5 t6')
select * from #t t
outer apply
(
select max(case when seq = 1 then val end) col1,
max(case when seq = 2 then val end) col2,
max(case when seq = 3 then val end) col3,
max(case when seq = 4 then val end) col4,
max(case when seq = 5 then val end) col5,
max(case when seq = 6 then val end) col6
from dbo.f_split(t.txt, ' ')
) b