Reputation: 1533
I am trying to create a bit complex stored procedure in ms sql database. My main focus is take a input of long string text then split the data by characters and update that data where matching. In detail: DataString
is the input long text string which will contain value like bellow example.
'-'
is separator between name of data type and its value
','
is separator between two different kind of value
':'
is separator between two set of data, each set of data separates by :
Now can u tell me how can i grab each data from long string and insert them where matching? Ask question if you still need to know something. Thanks in advance
Example of long text string:
ASIN-NsQf8,type-0,Price-7,IsPrime-1:ASIN-fD5tsQ,type-1,Price-13,IsPrime-0:ASIN-tvQtsu,type-1,Price-14,IsPrime-1
The Unfinished SQL Code:
CREATE PROCEDURE dbo.lk_UpdateMatchingDataOfThirdparty
@DataString VARCHAR(MAX)
AS
BEGIN
SET NOCOUNT ON;
UPDATE ThirdPartyData SET Price = @value_get_from_string, IsPrime = @value_get_from_string, DateChecked = GETDATE()
WHERE ASIN = '@value_get_from_string' AND type = '@value_get_from_string';
END
GO
Upvotes: 0
Views: 84
Reputation: 82000
Unfortunately string_split() does NOT return a sequence number. So if you are open to a an alternative split/parse function which is also performant.
Note: I made assumptions with the try_convert() portion
Example
Declare @DataString varchar(max) = 'ASIN-NsQf8,type-0,Price-7,IsPrime-1:ASIN-fD5tsQ,type-1,Price-13,IsPrime-0:ASIN-tvQtsu,type-1,Price-14,IsPrime-1'
UPDATE A
SET Price = B.Price
, IsPrime = B.IsPrime
, DateChecked = GETDATE()
From ThirdPartyData A
Join (
Select [ASIN] =replace(max(case when B.RetVal Like 'ASIN-%' then B.RetVal end),'ASIN-','')
,[Type] =try_convert(int,replace(max(case when B.RetVal Like 'type-%' then B.RetVal end),'type-',''))
,[Price] =try_convert(money,replace(max(case when B.RetVal Like 'price-%' then B.RetVal end),'price-',''))
,[IsPrime]=try_convert(bit,replace(max(case when B.RetVal Like 'IsPrime-%' then B.RetVal end),'IsPrime-',''))
From [dbo].[tvf-Str-Parse](@DataString,':') A
Cross Apply [dbo].[tvf-Str-Parse](A.RetVal,',') B
Group By A.RetSeq
) B
on A.[ASIN]=B.[ASIN] and A.[Type]=B.[Type]
If it Helps with the Visualization, the sub-query Returns
ASIN Type Price IsPrime
tvQtsu 1 14.00 1
NsQf8 0 7.00 1
fD5tsQ 1 13.00 0
The TVF if Interested
CREATE FUNCTION [dbo].[tvf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
Returns Table
As
Return (
Select RetSeq = Row_Number() over (Order By (Select null))
,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
From (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A
Cross Apply x.nodes('x') AS B(i)
);
EDIT: If you want the 2016+
string_split()
approach
Select [ASIN] =replace(max(case when Value Like 'ASIN-%' then Value end),'ASIN-','')
,[Type] =try_convert(int,replace(max(case when Value Like 'type-%' then Value end),'type-',''))
,[Price] =try_convert(money,replace(max(case when Value Like 'price-%' then Value end),'price-',''))
,[IsPrime]=try_convert(bit,replace(max(case when Value Like 'IsPrime-%' then Value end),'IsPrime-',''))
From (
Select A.RN
,B.*
From ( Select RN=Row_Number() over (Order by (select null)),* from string_split(@DataString,':') ) A
Cross Apply string_split(A.Value,',') B
) A
Group By RN
Upvotes: 1