How can I split string based on combination of characters? - sql-server

I have this string:
'Hello my Name is #!Jospeh#!'. I want my Output to be Jospeh.
Lets say if i have this string:
'Hello my Name is #!Joseph#! #!King#!'. I want my Output to me 'Joseph' and 'King'
I have created a function:
ALTER FUNCTION [dbo].[TfSplitTemplateVariable]
(
#String NVARCHAR(4000) ,
#Delimiter NCHAR(2)
)
RETURNS TABLE
AS
RETURN
(
WITH Split ( stpos, endpos )
AS ( SELECT 0 AS stpos ,
CHARINDEX(#Delimiter, #String) AS endpos
UNION ALL
SELECT endpos + 1 ,
CHARINDEX(#Delimiter, #String, endpos + 1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER ( ORDER BY ( SELECT 1
) ) ,
'Data' = SUBSTRING(#String, stpos,
COALESCE(NULLIF(endpos, 0), LEN(#String) + 1)
- stpos)
FROM Split
)
GO
And when i run this:
SELECT tstv.* FROM dbo.TfSplitTemplateVariable('Hello my Name is #!Jospeh#!','#!') AS tstv WHERE ID % 2 = 0
I get output !Jospeh.
What am i doing wrong

Change SELECT endpos + 1 to SELECT endpos + LEN(#Delimiter).

I hope this code suite your needs:
ALTER FUNCTION [dbo].[TfSplitTemplateVariable]
(
#String NVARCHAR(MAX),
#Delimiter NVARCHAR(2)
)
RETURNS #result TABLE (Id INT IDENTITY PRIMARY KEY, Data NVARCHAR (MAX))
AS
BEGIN
DECLARE #start INT, #end INT
SET #start = 1
WHILE CHARINDEX(#Delimiter, #String, #start) > 0
BEGIN
SET #start = CHARINDEX(#Delimiter, #String, #start) + LEN(#Delimiter)
SET #end = CHARINDEX(#Delimiter, #String, #start)
IF #end > #start
BEGIN
INSERT #result(Data) VALUES(SUBSTRING(#String, #start, #end - #start))
END
ELSE
BEGIN
BREAK
END
SET #start = #end + LEN(#Delimiter)
END
RETURN
END
GO

Related

How to get the result of string_split() in a row?

I want to split comma separated values using string_split(#var,',') I want any single row of the result into a variable . How do we do that in SQL server?
You Can try this function
CREATE FUNCTION [dbo].[fnSplitString]
(
#string NVARCHAR(MAX),
#delimiter CHAR(1)
)
RETURNS #output TABLE(splitdata NVARCHAR(MAX)
)
BEGIN
DECLARE #start INT, #end INT
SELECT #start = 1, #end = CHARINDEX(#delimiter, #string)
WHILE #start < LEN(#string) + 1 BEGIN
IF #end = 0
SET #end = LEN(#string) + 1
INSERT INTO #output (splitdata)
VALUES(SUBSTRING(#string, #start, #end - #start))
SET #start = #end + 1
SET #end = CHARINDEX(#delimiter, #string, #start)
END
RETURN
END
EXAMPLE
DECLARE #StringArray VARCHAR(max)
Set #StringArray= 'a,b,c,d,f';
select * from dbo.fnSplitString(#StringArray,',')
-- =============================================
-- fn_split50
-- split string by delimiter and return values in columns (value1, value2,...,value50)
-- if count of value > [#columnCnt] or [50] wraps other value to the next line:
-- so it allows to get "array data"
-- nn will indicare rowNo (from 1)
-- faster then dbo.fn_GetToken(), because process whole string at once
-- =============================================
/*
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5', ',', DEFAULT)
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10', ',', 3)
select * from dbo.fn_split50('zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10,zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10,zz1,aa2,ss3,dd4,ff5,gg6,hh7,jj8,ww9,qq10', ',', 3)
select * from dbo.fn_split50('zz1,11,aa2,22,ss3,33,dd4,44,ff5,55,gg6,66,hh7,77,jj8,88,ww9,99,qq10,1010', ',',2)
*/
alter FUNCTION fn_Split50
(
#str varchar(max),
#delim char(1),
#columnCnt int = 50
)
RETURNS TABLE
AS
RETURN
(
SELECT *
FROM (SELECT
nn = (nn - 1) / #columnCnt + 1,
nnn = 'value' + cast(((nn - 1) % #columnCnt) + 1 as varchar(10)),
value
FROM (SELECT
nn = ROW_NUMBER() over (order by (select null)),
value
FROM string_split(#str, #delim) aa
) aa
where nn > 0
) bb
PIVOT
(
max(value)
FOR nnn IN (
value1, value2, value3, value4, value5, value6, value7, value8, value9, value10,
value11, value12, value13, value14, value15, value16, value17, value18, value19, value20,
value21, value22, value23, value24, value25, value26, value27, value28, value29, value30,
value31, value32, value33, value34, value35, value36, value37, value38, value39, value40,
value41, value42, value43, value44, value45, value46, value47, value48, value49, value50
)
) AS PivotTable
)

Error converting data type varchar to float when splitting String

I am trying to split a string however its of data type varchar so to throws an error saying it cannot be converted to a float. I have tried but cant find a solution. How can i can i do it.
(SELECT Value FROM dbo.SplitString('648-44-21001-13764 ', '-') WHERE Position = 3)
Create FUNCTION SplitString
(
#Input NVARCHAR(MAX),
#Character CHAR(1)
)
RETURNS #Output TABLE (
Value NVARCHAR(1000),
Position int
)
AS
BEGIN
DECLARE #StartIndex INT, #EndIndex INT,#Position int
SET #Position = 0
SET #StartIndex = 1
IF SUBSTRING(#Input, LEN(#Input) - 1, LEN(#Input)) <> #Character
BEGIN
SET #Input = #Input + #Character
END
WHILE CHARINDEX(#Character, #Input) > 0
BEGIN
SET #EndIndex = CHARINDEX(#Character, #Input)
INSERT INTO #Output(Value,Position)
SELECT SUBSTRING(#Input, #StartIndex, #EndIndex - 1),#Position
SET #Input = SUBSTRING(#Input, #EndIndex + 1, LEN(#Input))
set #Position=#Position+1;
END
RETURN
END
GO
Check your Function Value column return type, it seems VARCHAR so You have to explicit convert it to float:
ALTER FUNCTION [dbo].[SplitString]
(
#String NVARCHAR(4000),
#Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(#Delimiter,#String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(#Delimiter,#String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Position' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Value' = SUBSTRING(#String,stpos,COALESCE(NULLIF(endpos,0),LEN(#String)+1)-stpos)
FROM Split
)
SELECT CAST((SELECT Value FROM dbo.SplitString('648-44-21001-13764 ', '-') WHERE Position = 3) AS FLOAT)

order by column based on starting Number(Number may be decimal) in a string in sql server

i have a column named name in my table and example data i have included below
name
-----
1.arun888
2.nikl55555
11.abcd5566
1.123.bhdf
2.767ss777
1.21cdm
and i want to sort the deatils like below
name
----
1.arun888
1.123.bhdf
1.21cdm
2.nikl55555
2.767ss777
11.abcd5566
I have tried many ways but nothing works for me
first method i had used
DECLARE #string varchar(100),
#start int,
#end int,
#len int
SET #string = '66555.12tttthe hollies 12345 Test Ad77dress Dr.'
set #string = replace(#string, ' ' , '')
set #len = len(#string)
set #start = PATINDEX('%[0-9]%',#string)
set #end = PATINDEX('%[^0-9]%',substring(#string, #start, #len))-1
print substring(#string, #start, #end)
but it gives only 66555
but i need
66555.12
second method i had used
CREATE FUNCTION dbo.fn_GetNumeric
(#strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
DECLARE #intAlpha INT
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric)
BEGIN
WHILE #intAlpha > 0
BEGIN
SET #strAlphaNumeric = STUFF(#strAlphaNumeric, #intAlpha, 1, '' )
SET #intAlpha = PATINDEX('%[^0-9]%', #strAlphaNumeric )
END
END
RETURN ISNULL(#strAlphaNumeric,0)
END
GO
i have used the above function but it wil return all the numbers from string
example
if string is 12.dddh5555
then it return 125555
so i am stuck here. i hope somebody can help me to find this
Try this code:
DECLARE #t TABLE ( name VARCHAR(20) )
INSERT INTO #t
VALUES ( '1.arun888' ),
( '2.nikl55555' ),
( '11.abcd5566' ),
( '1.123.bhdf' ),
( '2.767ss777' ),
( '1.21cdm' );
WITH cte
AS ( SELECT name ,
SUBSTRING(name, 1, PATINDEX('%[^0-9.]%', name) - 1) d
FROM #t
)
SELECT *
FROM cte
ORDER BY CAST(CASE WHEN RIGHT(d, 1) = '.' THEN SUBSTRING(d, 1, LEN(d) - 1)
WHEN d = '' THEN '0'
ELSE d
END AS DECIMAL(30, 10))
First I select substrings till the first symbol that is not dot or digit. Then just remove last dot and order by the result.
With function:
CREATE FUNCTION dbo.fn_GetNumeric
(
#strAlphaNumeric VARCHAR(256)
)
RETURNS DECIMAL(30, 10)
AS
BEGIN
DECLARE #s1 VARCHAR(256) = SUBSTRING(#strAlphaNumeric, 1,
PATINDEX('%[^0-9.]%',
#strAlphaNumeric) - 1)
RETURN CAST(CASE WHEN RIGHT(#s1, 1) = '.' THEN SUBSTRING(#s1, 1, LEN(#s1) - 1)
WHEN #s1 = '' THEN '0'
ELSE #s1
END AS DECIMAL(30, 10))
END
GO
SELECT * FROM TableName
ORDER BY dbo.fn_GetNumeric(name)

SQL Server: Does an UPDATE statement is faster if the table has indexes?

I need to insert 1.5 Million records into a table with the following layout:
MyEdition
(
MyEdition_ID INT,
MyEntity_ID INT,
copyType_ID INT,
MyEdition_CopyText VARCHAR(MAX)
)
I'm disabling all the INDEXES (both the clustered and non-clustered) and TRIGGERS on the table before inserting records from a temp table.
I need to strip-out all the HTML tags (except Bold, Italic and Underline tags) from the MyEdition_CopyText column from all 1.5M rows, so I'm performing an UPDATE on the table which uses a SQL function to strip out HTML tags within the MyEdition_CopyText column.
To summarise what I'm doing:
ALTER INDEX [MyEdition_reindex] ON [MyEdition] DISABLE (similarly all other indexes)
ALTER TABLE [dbo].[MyEdition] DISABLE TRIGGER ALL;
INSERT INTO MyEdition(<columns>) SELECT <columns> FROM <#my_temp_table>
UPDATE MyEdition SET MyEdition_CopyText = dbo.StripHTML(MyEdition_CopyText)
REBULID INDEXES
ENABLE TRIGGERS
The UPDATE statement is taking a little while, so I wonder if this is because all the indexes were disabled? What would be the best approach to strip out the HTML characters from the column?
Any suggestions on how this could be improved? How SQL Server make use of indexes whilst performing an UPDATE operation?
I'm using the following SQL function:
ALTER FUNCTION [dbo].[StripOutHTML]
(
#HTMLText VARCHAR(max),
#stripDisallowedOnly BIT
)
returns VARCHAR(max)
AS
BEGIN
DECLARE #Start INT
DECLARE #End INT
DECLARE #Length INT
-- Replace the HTML entity & with the '&' character (this needs to be done first, as
-- '&' might be double encoded as '&')
SET #Start = Charindex('&', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '&')
SET #Start = Charindex('&', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
END
-- Replace the HTML entity < with the '<' character
SET #Start = Charindex('<', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '<')
SET #Start = Charindex('<', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
END
-- Replace the HTML entity > with the '>' character
SET #Start = Charindex('>', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '>')
SET #Start = Charindex('>', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
END
-- Replace the HTML entity & with the '&' character
SET #Start = Charindex('&amp;', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '&')
SET #Start = Charindex('&amp;', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
END
-- Replace the HTML entity with the ' ' character
SET #Start = Charindex(' ', #HTMLText)
SET #End = #Start + 5
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, ' ')
SET #Start = Charindex(' ', #HTMLText)
SET #End = #Start + 5
SET #Length = ( #End - #Start ) + 1
END
-- Replace any <P>, </P>tags with a <BR>, so they will be replaced with a new line in next step
SET #HTMLText = REPLACE(#HTMLText, '<P>', '<br>')
SET #HTMLText = REPLACE(#HTMLText, '</P>', '<br>')
-- Replace any <BR> tags with a newline
SET #Start = Charindex('<br>', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length,
Char(13) + Char(10))
SET #Start = Charindex('<br>', #HTMLText)
SET #End = #Start + 3
SET #Length = ( #End - #Start ) + 1
END
-- Replace any tags with a newline
SET #Start = Charindex('<br/>', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length,
'CHAR(13) + CHAR(10)')
SET #Start = Charindex('<br/>', #HTMLText)
SET #End = #Start + 4
SET #Length = ( #End - #Start ) + 1
END
-- Replace any tags with a newline
SET #Start = Charindex('<br />', #HTMLText)
SET #End = #Start + 5
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length,
'CHAR(13) + CHAR(10)')
SET #Start = Charindex('<br />', #HTMLText)
SET #End = #Start + 5
SET #Length = ( #End - #Start ) + 1
END
-- Remove anything between tags
SET #Start = Charindex('<', #HTMLText)
SET #End = Charindex('>', #HTMLText, Charindex('<', #HTMLText))
SET #Length = ( #End - #Start ) + 1
WHILE ( #Start > 0
AND #End > 0
AND #Length > 0 )
BEGIN
IF #stripDisallowedOnly = 1
BEGIN
IF ( Upper(Substring(#HTMLText, #Start, 2)) <> '<B' )
AND ( Upper(Substring(#HTMLText, #Start, 3)) <> '</B' )
AND ( Upper(Substring(#HTMLText, #Start, 2)) <> '<U' )
AND ( Upper(Substring(#HTMLText, #Start, 3)) <> '</U' )
AND ( Upper(Substring(#HTMLText, #Start, 2)) <> '<I' )
AND ( Upper(Substring(#HTMLText, #Start, 3)) <> '</I' )
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '')
END
ELSE
BEGIN
SET #Length = 0
END
END
ELSE
BEGIN
SET #HTMLText = Stuff(#HTMLText, #Start, #Length, '')
END
SET #Start = Charindex('<', #HTMLText, #End - #Length)
SET #End = Charindex('>', #HTMLText, Charindex('<', #HTMLText,
#Start)
)
SET #Length = ( #End - #Start ) + 1
END
-- Remove any leading space/carriage return
DECLARE #trimchars VARCHAR(10)
SET #trimchars = CHAR(9)+CHAR(10)+CHAR(13)+CHAR(32)
IF #HTMLText LIKE '[' + #trimchars + ']%' SET #HTMLText = SUBSTRING(#HTMLText, PATINDEX('%[^' + #trimchars + ']%', #HTMLText), LEN(#HTMLText))
RETURN Ltrim(Rtrim(#HTMLText))
END
EDIT:
I have tested the following three ways:
Update all in one SQL statement.
UPDATE MyEdition SET MyEdition_Copy=[dbo].StripOutHTML(MyEdition_Copy, 1)
-- This approach took 3 hours
Updated 10000 records in one batch.
DECLARE #min INT, #max INT, #batchSize INT
SET #batchSize = 10000
SELECT #min=MIN(MyEdition_id), #max=MAX(MyEdition_id)
FROM MyEdition
--PRINT 'MAX:' + CAST(#max AS VARCHAR(50))
WHILE #min < #max
BEGIN
DECLARE #x varchar(max) = ''
SET #x = 'UPDATE MyEdition SET MyEdition_CopyText=dbo.StripOutHTML(MyEdition_CopyText, 1)'
+ 'WHERE (copytextedition_id BETWEEN ' + CAST(#min AS VARCHAR(50)) + ' AND ' + CAST((#min + #batchSize -1) AS VARCHAR(50)) + ');'
Exec(#x)
PRINT #x
SET #min = #min + #batchSize
END
-- This approach took 5 hours 20 minutes
Loaded the values into .Net program, Stripped those characters and saved into the database.
-- This approach took about 24 hours.
Indexes only help when you want to restrict the set of data being modified. In your case an index won't have any effect, as you update every record anyway. In fact, the update might even be quicker without indexes, if the indexes included the field that was being updated, as every update would cause the index to be changed.
Not necessarily an answer in this case, but I want to post this in case it is useful to anyone else who finds this post. Here is another way to do a large update in batches that doesn't involve using dynamic SQL and EXEC(), which probably is hurting performance to some degree:
(Note this approach requires SQL 2005 or higher, and a table with a unique key, called "PKColumn" in the code below)
DECLARE #BatchSize int = 50000;
DECLARE #RowNum int = 1;
WHILE 1=1
BEGIN
WITH cte AS (
SELECT PKColumn
FROM MyTable
WHERE ROW_NUMBER() OVER (ORDER BY PKColumn ASC) BETWEEN #RowNum AND (#RowNum + #BatchSize)
)
UPDATE t1
SET SomeColumn = SomeValue
FROM MyTable t1
INNER JOIN cte
ON t1.PKColumn=cte.PKColumn;
IF ##ROWCOUNT=0
BREAK;
ELSE
BEGIN
SET #RowNum = #RowNum + #BatchSize + 1;
CONTINUE;
END
END
I hope that's everything; I'm writing on the fly from memory without testing. You can try it, but I think because of your function, it's not going to be any faster.

Split and Replace the string in SqlServer 2008?

I want to split string 'GPIN-KH2-COH-24042014-02' by '-' in sqlserver 2008 and want to save in separate variables. How can I achieve this? Please help me in this regard.
Now I am using below function and pass it ('GPIN-KH2-COH-24042014-02', '-')
Create FUNCTION [dbo].[fnSplit]
(
#strInputList NVARCHAR (MAX), -- List of Delimited Items
#strDelimiter NVARCHAR (11) = ',' -- Delimiter that Separates Items
)
RETURNS #tblList TABLE (strItem NVARCHAR(250))
BEGIN
DECLARE #strItem NVARCHAR(MAX)
WHILE CHARINDEX(#strDelimiter,#strInputList,0) <> 0
BEGIN
SELECT
#strItem = RTRIM(LTRIM( (SUBSTRING (#strInputList, 1, CHARINDEX (#strDelimiter, #strInputList, 0) -1)))),
#strInputList = RTRIM(LTRIM( (SUBSTRING (#strInputList, CHARINDEX (#strDelimiter, #strInputList, 0) + LEN (#strDelimiter), LEN (#strInputList)))))
IF LEN(#strItem) > 0
INSERT INTO #tblList SELECT #strItem
END
IF LEN(#strInputList) > 0
INSERT INTO #tblList SELECT #strInputList
RETURN
END
Result:
strItem
GPIN
KH2
COH
24042014
02
When I was delimeter and string it return result in that table format as shown above. But I want to get last two rows. How can I get this?
CRETAE function and pass your string and Delimiter as parameter
FUNCTION:
CREATE FUNCTION [dbo].[Split](#String varchar(8000), #Delimiter char(1))
returns #temptable TABLE (items varchar(8000))
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)
insert into #temptable(Items) values(#slice)
set #String = right(#String,len(#String) - #idx)
if len(#String) = 0 break
end
return
end
And then call the function and use the values as you want
DECLARE #A VARCHAR (100)= 'GPIN-KH2-COH-24042014-02'
SELECT items
INTO #STRINGS
FROM dbo.split(#A,'-')
select * from #STRINGS
Use this function, download from here
usage
SELECT DBO.fnString_DelimeterIndex(N'GPIN-KH2-COH-24042014-02','-',1)
SELECT DBO.fnString_DelimeterIndex(N'GPIN-KH2-COH-24042014-02','-',2)
SELECT DBO.fnString_DelimeterIndex(N'GPIN-KH2-COH-24042014-02','-',3)
function
ALTER FUNCTION [dbo].[fnString_DelimeterIndex]
(
#Text NVARCHAR(4000),
#Delimiter CHAR,
#Section SMALLINT
)
RETURNS NVARCHAR(4000)
AS
BEGIN
DECLARE #NextPos SMALLINT,
#LastPos SMALLINT,
#Found SMALLINT,
#REVERSE BIT
IF #Section < 0
SELECT #Text = REVERSE(#Text)--, #Section=1,#REVERSE=1
SELECT #NextPos = CHARINDEX(#Delimiter, #Text, 1),
#LastPos = 0,
#Found = 1
WHILE #NextPos > 0 AND ABS(#Section) <> #Found
SELECT #LastPos = #NextPos,
#NextPos = CHARINDEX(#Delimiter, #Text, #NextPos + 1),
#Found = #Found + 1
RETURN CASE
WHEN #Found <> ABS(#Section) OR #Section = 0 THEN NULL
--WHEN #REVERSE =1 THEN
WHEN #Section > 0 THEN SUBSTRING(#Text, #LastPos + 1, CASE WHEN #NextPos = 0 THEN DATALENGTH(#Text) - #LastPos ELSE #NextPos - #LastPos - 1 END)
ELSE REVERSE(SUBSTRING(#Text, #LastPos + 1, CASE WHEN #NextPos = 0 THEN DATALENGTH(#Text) - #LastPos ELSE #NextPos - #LastPos - 1 END))
END
END
Here is a fancy way of solving it:
You need a function to split it first:
create function [dbo].[f_specialsplit]
(
#param nvarchar(max),
#delimiter char(1)
)
returns #t table (val nvarchar(max), rn varchar(9))
as
begin
set #param += #delimiter
;with a as
(
select cast(1 as bigint) f, charindex(#delimiter, #param) t where #param is not null
union all
select t + 1, charindex(#delimiter, #param, t + 1)
from a
where charindex(#delimiter, #param, t + 1) > 0
)
insert #t
select substring(#param, f, t - f), row_number() over (order by (select 1)) from a
option (maxrecursion 0)
return
end
Trick is now to pivot the data into the variables:
DECLARE #str varchar(100) = 'GPIN-KH2-COH-24042014-02'
DECLARE #s1 varchar(100),#s2 varchar(100),#s3 varchar(100),#s4 varchar(100),#s5 varchar(100)
SELECT #s1=[1],#s2=[2],#s3=[3],#s4=[4],#s5=[5]
FROM f_specialsplit(#str,'-')
PIVOT
(min([val])
FOR rn
in([1],[2],[3],[4],[5])
)AS p
SELECT #s1,#s2,#s3,#s4,#s5
Result:
GPIN KH2 COH 24042014 02

Resources