I've been trying to write a Table-Valued function that takes value pairs as a parameter and return a table with two columns.
Below is the function signature I am trying to do.
FUNCTION [dbo].[ValuePairParser]( #DelimitedValuePairs VARCHAR(MAX),
#Delimiter CHAR(1),
#ValuePairDelimiter CHAR(1) )
RETURNS #ValuePairTable
TABLE ( Id INT, Code INT )
I want to call the method like below
#ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3, 1000:230, 130:120,'
ValuePairParser (#ValuePairs, ',', ':')
Can you see any nice way to split above ValuePairs sting and create a table with two columns?
CREATE FUNCTION [dbo].[SplitWithPairs]
(
#List NVARCHAR(MAX),
#MajorDelimiter VARCHAR(3) = ',',
#MinorDelimiter VARCHAR(3) = ':'
)
RETURNS #Items TABLE
(
Position INT IDENTITY(1,1) NOT NULL,
LeftItem INT NOT NULL,
RightItem INT NOT NULL
)
AS
BEGIN
DECLARE
#Item NVARCHAR(MAX),
#LeftItem NVARCHAR(MAX),
#RightItem NVARCHAR(MAX),
#Pos INT;
SELECT
#List = #List + ' ',
#MajorDelimiter = LTRIM(RTRIM(#MajorDelimiter)),
#MinorDelimiter = LTRIM(RTRIM(#MinorDelimiter));
WHILE LEN(#List) > 0
BEGIN
SET #Pos = CHARINDEX(#MajorDelimiter, #List);
IF #Pos = 0
SET #Pos = LEN(#List) + LEN(#MajorDelimiter);
SELECT
#Item = LTRIM(RTRIM(LEFT(#List, #Pos - 1))),
#LeftItem = LTRIM(RTRIM(LEFT(#Item,
CHARINDEX(#MinorDelimiter, #Item) - 1))),
#RightItem = LTRIM(RTRIM(SUBSTRING(#Item,
CHARINDEX(#MinorDelimiter, #Item)
+ LEN(#MinorDelimiter), LEN(#Item))));
INSERT #Items(LeftItem, RightItem)
SELECT #LeftItem, #RightItem;
SET #List = SUBSTRING(#List,
#Pos + LEN(#MajorDelimiter), DATALENGTH(#List));
END
RETURN;
END
GO
DECLARE #ValuePairs VARCHAR(MAX) = '1:1, 1:2, 1:4, 2:3,1000:230, 130:120,';
SELECT LeftItem, RightItem
FROM dbo.SplitWithPairs(#ValuePairs, ',', ':')
ORDER BY Position;
GO
create function ValuePairParser(#DelimitedValuePairs varchar(MAX),
#Delimiter char(1),
#ValuePairDelimiter char(1))
returns #ValuePairTable table(Id int, Code int) as
begin
with Split(ValuePair, Rest) as
(
select left(#DelimitedValuePairs, charindex(#Delimiter, #DelimitedValuePairs)-1),
stuff(#DelimitedValuePairs, 1, charindex(#Delimiter, #DelimitedValuePairs), '')
where charindex(#Delimiter, #DelimitedValuePairs) > 0
union all
select left(Rest, charindex(#Delimiter, Rest)-1),
stuff(Rest, 1, charindex(#Delimiter, Rest), '')
from Split
where charindex(#Delimiter, Rest) > 0
)
insert into #ValuePairTable
select left(ValuePair, charindex(#ValuePairDelimiter, ValuePair)-1),
stuff(ValuePair, 1, charindex(#ValuePairDelimiter, ValuePair), '')
from Split
option (maxrecursion 0)
return
end
Related
I have a sql table that contains an employee's full name in all caps (i.e. SMITH-EASTMAN,JIM M).
I need to be able to separate the full name into two separate columns (Last Name and First Name). This part is going well. Now I could use some assistance with removing the capital letters and putting it in normal case.
How can I take the results of my common table expression and pass them into a function?
WITH CTE AS
(
SELECT FullName = [Employee Name],
LastName = SUBSTRING([Employee Name], 1, CHARINDEX(',',[Employee Name])-1),
FirstNameStartPos = CHARINDEX(',',[Employee Name]) + 1,
MidlleInitialOrFirstNameStartPos = CHARINDEX(' ',[Employee Name]),
MiddleInitialOrSecondFirstName = SUBSTRING([Employee Name], CHARINDEX(' ',[Employee Name]),LEN([Employee Name])),
MiddleInitialOrSecondFirstNameLen = LEN(SUBSTRING([Employee Name], CHARINDEX(' ',[Employee Name]),LEN([Employee Name]))) - 1
FROM ['Med-PS PCN Mapping$']
WHERE [PS Employee ID] IS NOT NULL
),
CTE2 AS
(
SELECT FullName = CTE.FullName,
DerivedFirstName = CASE
WHEN CTE.MiddleInitialOrSecondFirstNameLen = 1
THEN SUBSTRING(CTE.FullName, CTE.FirstNameStartPos, CTE.MidlleInitialOrFirstNameStartPos - CTE.FirstNameStartPos)
ELSE SUBSTRING(CTE.FullName, CTE.FirstNameStartPos, CTE.FirstNameStartPos + CTE.MiddleInitialOrSecondFirstNameLen)
END,
DerivedLastName = CTE.LastName
FROM CTE
)
SELECT *
FROM CTE2
RESULTS
FullName DerivedFirstName DerivedLastName
SMITH-EASTMAN,JIM M JIM SMITH-EASTMAN
O'DAY,MARTIN C MARTIN O'DAY
TROUT,MADISON MARIE MADISON MARI TROUT
CREATE FUNCTION [dbo].[FixCap] ( #InputString varchar(4000) )
RETURNS VARCHAR(4000)
AS
BEGIN
DECLARE #Index INT
DECLARE #Char CHAR(1)
DECLARE #PrevChar CHAR(1)
DECLARE #OutputString VARCHAR(255)
SET #OutputString = LOWER(#InputString)
SET #Index = 1
WHILE #Index <= LEN(#InputString)
BEGIN
SET #Char = SUBSTRING(#InputString, #Index, 1)
SET #PrevChar = CASE WHEN #Index = 1 THEN ' '
ELSE SUBSTRING(#InputString, #Index - 1, 1)
END
IF #PrevChar IN (' ', ';', ':', '!', '?', ',', '.', '_', '-', '/', '&', '''', '(')
BEGIN
IF #PrevChar != '''' OR UPPER(#Char) != 'S'
SET #OutputString = STUFF(#OutputString, #Index, 1, UPPER(#Char))
END
SET #Index = #Index + 1
END
RETURN #OutputString
END
GO
select [dbo].[FixCap] (pass in DerivedFirstName from CTE2);
select [dbo].[FixCap] (pass in DerivedLastName from CTE2);
Do you want something like INITCAP ?
CREATE FUNCTION dbo.F_INITCAP (#PHRASE NVARCHAR(max))
RETURNS NVARCHAR(max)
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
IF LEN(#PHRASE) < 1 RETURN #PHRASE;
DECLARE #I INT = 1, #C CHAR(1), #P BIT = 0, #OUT VARCHAR(max) = '';
WHILE #I <= LEN(#PHRASE)
BEGIN
SET #C = SUBSTRING(#PHRASE, #I, 1);
IF #C BETWEEN 'A' AND 'Z' COLLATE Latin1_General_CI_AI
BEGIN
IF #P = 0
SET #OUT = #OUT + UPPER(#C);
ELSE
SET #OUT = #OUT + LOWER(#C);
SET #P = 1
END
ELSE
BEGIN
SET #P = 0;
SET #OUT = #OUT + LOWER(#C);
END
SET #I = #I + 1;
END
RETURN #OUT;
END
GO
I currently have a function in SQL that places a tilde every 60 characters, but the original text already has tilde's so , basically I want to change that if there is a tilde and the next tilde is under 60 characters away, then skip to the next tilde. If its over 60 characters, then only then place a extra tilde.
My current function looks like;
function [dbo].[AddTilde] (
#string varchar(max),
#count int
)
returns varchar(max)
as
begin
declare #result varchar(max) = ''
declare #token varchar(max) = ''
while DATALENGTH(#string) > 0
begin
select #token = left(#string, #count)
select #string = REPLACE(#string, #token, '')
select #result +=#token +case when DATALENGTH(#string)=0 then '' else '~' end
end
return #result
end
Any help appreciated
Many Thanks
DECLARE #string1 VARCHAR(max),
#string2 VARCHAR(max) = '',
#i1 INT,
#i2 INT
SET #string1 = '12345678901234567890~1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
WHILE LEN(#string1) > 0
BEGIN
SET #i1 = CHARINDEX('~',#string1)
SET #i2 = #i1 - (ABS(#i1-60) + (#i1-60)) / 2 -- MINIMUM OF ~ LOCATION AND 60
SET #i1 = LEN(#string1)
IF #i2 = 0 SET #i2 = #i1 - (ABS(#i1-60) + (#i1-60)) / 2 -- MINIMUM OF LENGTH OF #string1 LOCATION AND 60
IF #i2 < 60
BEGIN
SET #string2 = #string2 + LEFT(#string1,#i2)
SET #string1 = RIGHT(#string1,#i1-#i2)
END
ELSE
BEGIN
SET #string2 = #string2 + LEFT(#string1,60) + '~'
SET #string1 = RIGHT(#string1,#i1-60)
END
END
Results: 12345678901234567890~123456789012345678901234567890123456789012345678901234567890~1234567890123456789012345678901234567890
This is based on my String Splitting function, which has a very good performance.
This function should be quite efficient, albeit hard to understand (I have added a few commenets in attempt to make it easier).
You can change internal parameters easily e.g. #Delimitor can be multiple characters
Test cases are included at the bottom.
ALTER FUNCTION [dbo].[AddTilde]
(
#String VARCHAR( MAX ),
#Count INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #CurrentPosition BIGINT, #NextDelimiterPosition BIGINT, #NextFixedPosition BIGINT, #NextPosition BIGINT,
#DelimiterLength INT, #Delimiter VARCHAR( 5 ), #Result VARCHAR( MAX )
-- Initialise
SET #Delimiter = '~'
SET #DelimiterLength = LEN( #Delimiter )
SET #Result = ''
-- Ensures we can terminate loop without using an extra IF condition, saves a few = 0 checks
SET #String = #String + #Delimiter
SET #CurrentPosition = 1
-- Check for next Tilde position
SET #NextDelimiterPosition = CHARINDEX( #Delimiter, #String, #CurrentPosition )
-- Initialise fixed increment position
SET #NextFixedPosition = #Count
-- Compare, which one is earlier and use that one. Handle cases where the next token begins with Tilde
SET #NextPosition = CASE WHEN #NextDelimiterPosition - #DelimiterLength > #NextFixedPosition THEN #NextFixedPosition ELSE #NextDelimiterPosition END
WHILE #NextDelimiterPosition > 0
BEGIN
SET #Result = #Result + SUBSTRING( #String, #CurrentPosition, #NextPosition - #CurrentPosition + 1 )
-- Handle cases where the next token begins with Tilde and avoids doubling up Tildes
+ ( CASE WHEN #NextPosition = #NextDelimiterPosition THEN '' ELSE #Delimiter END )
SET #CurrentPosition = #NextPosition + 1
-- Increment fixed position
SET #NextFixedPosition = #CurrentPosition + #Count - 1
-- Check for next Tilde position
SET #NextDelimiterPosition = CHARINDEX( #Delimiter, #String, #CurrentPosition )
SET #NextPosition = CASE WHEN #NextDelimiterPosition - #DelimiterLength > #NextFixedPosition THEN #NextFixedPosition ELSE #NextDelimiterPosition END
END
-- Remove trailing Tilde
SET #Result = SUBSTRING( #Result, 1, LEN( #Result ) - #DelimiterLength )
RETURN #Result
END
/* Test Cases
SELECT dbo.[AddTilde]( 'ab~c~defghijkl~', 3 ) --> 'ab~c~def~ghi~jkl~'
SELECT dbo.[AddTilde]( '~ab~c~defghijkl', 3 ) --> '~ab~c~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'ab~c~~defghijkl', 3 ) --> 'ab~c~~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'abcdefghijkl', 3 ) --> 'abc~def~ghi~jkl'
SELECT dbo.[AddTilde]( 'a', 3 ) --> 'a'
*/
I have my table with Column MailText which has values like
1. <strong>abc</strong>:<description1> <strong>bcd</strong>:<description2>
2. <strong>efg</strong>:<description3> <strong>hgl</strong>:<description7>
Upon update I want values like
1. <strong>abc</strong>:<abc> <strong>bcd</strong>:<bcd>
2. <strong>efg</strong>:<efg> <strong>hgl</strong>:<hgl>
Please help with dynamic replacement that it would update all string within <strong> tag to <description>. <strong> tag may contain any values.
CREATE FUNCTION GetString
(
#s NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
DECLARE #trav NVARCHAR(2000) = #s,
#length INT,
#count INT = 1,
#startIndex INT = 0,
#endIndex INT = 0,
#replaceStartIndex INT = 0,
#repalceEndIndex INT = 0,
#replaceword NVARCHAR(2000),
#newWord NVARCHAR(2000)
SELECT #length = LEN(#Trav)
WHILE ((#count + #startIndex) <= #length)
BEGIN
SET #startIndex = CHARINDEX('<strong>', #trav, #startIndex) + LEN('<strong>')
IF (#startIndex > 8)
BEGIN
SET #endIndex = CHARINDEX('</strong>', #trav, #startIndex)
SET #newWord = SUBSTRING(#trav, #startIndex, (#endIndex - #startIndex))
SET #replaceStartIndex = CHARINDEX(':', #trav, #startIndex) + 2
SET #repalceEndIndex = CHARINDEX('>', #trav, #replaceStartIndex)
SET #replaceword = SUBSTRING(
#trav,
#replaceStartIndex,
(#repalceEndIndex - #replaceStartIndex)
)
--SELECT #replaceword as 'repword', #newWord as 'newword'
SET #trav = REPLACE (#trav, #replaceword, #newWord)
SET #count = #repalceEndIndex
END
ELSE
BEGIN
SET #count = #count + 1
END
END
RETURN #trav
END
GO
IF OBJECT_ID('tempdb..#table') IS NOT NULL
DROP TABLE #table
CREATE TABLE #table
(
string VARCHAR(1000)
)
INSERT INTO #table
SELECT
'1. <strong>abc</strong>:<description1> <strong>bcd</strong>:<description2>'
INSERT INTO #table
SELECT
'2. <strong>efg</strong>:<description3> <strong>hgl</strong>:<description7>'
UPDATE #table
SET string = [dbo].[GetString](#table.string)
SELECT *
FROM #table
I have my table like this
4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione
10-Contrassegno
12-Documenti di annullo polizza-10-Contrassegno
10-Contrassegno
12-Documenti di annullo polizza-10-Contrassegno
I want to split every row to be like this
4-3-2
10
12-10
10
12-10
try this
DECLARE #table AS TABLE
(
ID INT IDENTITY(1, 1) ,
SomeText VARCHAR(500)
)
INSERT INTO #table
( SomeText )
VALUES ( '4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione' ),
( '10-Contrassegno' ),
( '12-Documenti di annullo polizza-10-Contrassegno' ),
( '10-Contrassegno' ),
( '12-Documenti di annullo polizza-10-Contrassegno' );
WITH cte
AS ( SELECT n = 1
UNION ALL
SELECT n + 1
FROM cte
WHERE n <= 100
),
SplitToChr
AS ( SELECT T.ID ,
SUBSTRING(T.SomeText, cte.n, 1) AS Chr
FROM #table AS T
JOIN cte ON DATALENGTH(T.SomeText) >= cte.n
AND SUBSTRING(T.SomeText, cte.n, 1) LIKE '[0-9-]'
)
SELECT T.ID ,
REVERSE(SUBSTRING(REVERSE(T.FInal),2,LEN(T.FInal))) AS Final
FROM ( SELECT DISTINCT
o.ID ,
REPLACE(( SELECT '' + chr
FROM SplitToChr AS i
WHERE i.id = o.id
FOR
XML PATH('')
), '--', '-') AS FInal
FROM SplitToChr AS o
) AS T
SAMPLE TABLE
CREATE TABLE #TEMP(STRINGCOLUMN NVARCHAR(MAX))
INSERT INTO #TEMP
SELECT '4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione'
UNION ALL
SELECT '10-Contrassegno'
UNION ALL
SELECT '12-Documenti di annullo polizza-10-Contrassegno'
UNION ALL
SELECT '10-Contrassegno'
UNION ALL
SELECT '12-Documenti di annullo polizza-10-Contrassegno'
You can use a function in case you need the query to be simple
Function
CREATE FUNCTION [dbo].[ConvertToNumber]
(#strAlphaNumeric VARCHAR(256))
RETURNS VARCHAR(256)
AS
BEGIN
SET #strAlphaNumeric = LEFT(#strAlphaNumeric,
LEN(#strAlphaNumeric) - CHARINDEX('-', REVERSE(#strAlphaNumeric)) + 0)
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
And your final query
SELECT DBO.ConvertToNumber(STRINGCOLUMN)STRINGCOLUMN
FROM #TEMP
RESULT
first use this split func
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
and then use this code
CREATE TABLE #t10 ( id int identity(1,1)
, num int )
INSERT INTO #t10
select *
from dbo.fnSplitString ('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione','-')
WHERE ISNUMERIC(splitdata)=1
DECLARE #x int = 1
DECLARE #y varchar(10)=''
DECLARE #q varchar(10)
WHILE #x<=(SELECT count(*)
from #t10)
BEGIN
SET #q=(SELECT num
FROM #t10
WHERE id = #x )
set #y=#y+#q+'-'
SET #x=#x+1
END
SELECT left(ltrim(#y),len(#y)-1)
--SELECT * FROM #t10
--drop table #t10
It's a bit messy, but it gets the job done :-)
CREATE TABLE dbo.Documents (
Details VARCHAR(1000)
);
GO
INSERT INTO dbo.Documents
VALUES ('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione'),
('10-Contrassegno'),
('12-Documenti di annullo polizza-10-Contrassegno'),
('10-Contrassegno'),
('12-Documenti di annullo polizza-10-Contrassegno');
SELECT CASE WHEN (FirstLine + SecondLine + ThirdLine) LIKE '%-'
THEN LEFT(FirstLine + SecondLine + ThirdLine, LEN(FirstLine + SecondLine + ThirdLine) -1)
ELSE (FirstLine + SecondLine + ThirdLine) END AS CleanData
FROM (
SELECT
LEFT(Details, CHARINDEX('-', Details)) AS FirstLine,
REPLACE(CASE
WHEN REPLACE( REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2) , LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)), ''), LEFT(Details, CHARINDEX('-', Details)), '') LIKE '%[0-9]' THEN REPLACE( REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2) , LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)), ''), LEFT(Details, CHARINDEX('-', Details)), '') + '-'
ELSE REPLACE( LEFT(Details,CHARINDEX('-', Details, CHARINDEX('-', Details )+1)+2) , LEFT(Details, CHARINDEX('-', Details, CHARINDEX('-', Details)+1)), '')
END , LEFT(Details, CHARINDEX('-', Details)), '') AS SecondLine,
CASE WHEN REVERSE(LEFT(REVERSE(Details), CHARINDEX('-', REVERSE(Details))+2)) LIKE '-%'
THEN LEFT(REVERSE(LEFT(REVERSE(Details), CHARINDEX('-', REVERSE(Details))+2)), 3) ELSE '' END AS ThirdLine
FROM dbo.Documents
) AS A;
Another way of doing it in a much simpler way. Create a function to remove the alphabets from the string
Create FUNCTION dbo.RemoveAlphabets (#string VARCHAR(256))
returns VARCHAR(256)
BEGIN
IF #string IS NULL
RETURN NULL
DECLARE #Result VARCHAR(256)='',#len INT = Len(#string ),#cnt INT=1
WHILE #cnt <= #len
BEGIN
DECLARE #parse INT
SET #parse = Ascii(Substring(#string , #cnt, 1))
IF #parse BETWEEN 48 AND 57 or #parse =45
SET #Result = #Result + Char(#parse)
SET #cnt = #cnt + 1
END
select #result= replace(#Result,'--','-')
RETURN left(#result,case when right(#Result,1)='-' then len(#Result)-1 else len(#result) end)
END
If numbers inside the string is always surrounded by '-' then replace the return statement with this.
RETURN left(#result,len(#Result)-1)
execute the function
select dbo.RemoveAlphabets
('4-Documento d’identità-3-Attestato di Rischio-2-Carta di Circolazione')
Result : 4-3-2
have table
CREATE TABLE #tbl
(
id int identity(1,1),
obj_type int ,
obj_id nvarchar(50)
)
have data like : 153:0|114:0|147:0|148:0|152:0|155:0
want insert which data ise before " : " to obj_id , which data is next to " : " insert tu obj_type. it's must be like
id obj_type obj_id
1 0 153
2 0 114
3 0 147
4 0 148
5 0 152
6 0 155
How do it in stored procedure ? not function
declare #S varchar(100) = '153:0|114:0|147:0|148:0|152:0|155:0'
declare #xml xml
select #xml = '<item><value>'+replace(replace(#s, ':','</value><value>'), '|','</value></item><item><value>')+'</value></item>'
select N.value('value[1]', 'int') as obj_id,
N.value('value[2]', 'int') as obj_type
from #xml.nodes('item') as T(N)
SQL Fiddle
You can wait for some experts answer
till then you can give it one chance
insert into #tbl
SELECT LEFT(splitdata, CHARINDEX(':', splitdata) - 1) AS obj_id,
RIGHT(splitdata, CHARINDEX(':', REVERSE(splitdata)) - 1) AS obj_type from (select splitdatafrom fnSplitString(parameterName,'|')
now you can write stringsplit function like this
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
Another Solution :
Create FUNCTION [dbo].[SplitString]
(
#List NVARCHAR(MAX),
#Delim VARCHAR(255)
)
RETURNS TABLE
AS
RETURN ( SELECT [Value] FROM
(
SELECT
[Value] = LTRIM(RTRIM(SUBSTRING(#List, [Number],
CHARINDEX(#Delim, #List + #Delim, [Number]) - [Number])))
FROM (SELECT Number = ROW_NUMBER() OVER (ORDER BY name)
FROM sys.all_objects) AS x
WHERE Number <= LEN(#List)
AND SUBSTRING(#Delim + #List, [Number], LEN(#Delim)) = #Delim
) AS y
);
taken form: T-SQL split string
And then select the values:
Declare
#Text varchar (100) = '153:0|114:0|147:0|148:0|152:0|155:0',
#Delim varchar(50) = ':0|'
select case when CHARINDEX(':0', Value) > 0 then Left(Value, Len(Value)-2) else Value End AS Result from dbo.SplitString(#Text, #Delim)
CREATE procedure [dbo].[Insert_procedure]
#inputString varchar(max)
AS
BEGIN
set #inputString ='2153:770|114:0|147:0|148:0|152:0|155:0' Declare #delimiter char(1) = '|' Declare #delimiter_Colon char(1) = ':'
DECLARE #chIndex int DECLARE #chIndex1 int DECLARE #item varchar(100)Declare #ReverseString varchar(max)
SELECT #ReverseString = Reverse(substring(reverse(#inputString), 1, 1))
IF(#ReverseString <> '|')
set #inputString = #inputString +'|'
WHILE CHARINDEX(#delimiter, #inputString, 0) <> 0
BEGIN
SET #chIndex = CHARINDEX(#delimiter, #inputString, 0)
SELECT #item = SUBSTRING(#inputString, 1, #chIndex - 1)
IF LEN(#item) > 0
BEGIN
set #chIndex1 = CHARINDEX(#delimiter_Colon, #item, 0)
Declare #obj_type int Declare #obj_id varchar(50)
SELECT #obj_id = SUBSTRING(#item, #chIndex1+1,len(#item)) SELECT #obj_type = SUBSTRING(#item,1,#chIndex1-1)
Insert into TEST(obj_type,obj_id) values (#obj_type,#obj_id)
END
SELECT #inputString = SUBSTRING(#inputString, #chIndex + 1, LEN(#inputString))
END
END