Sql server 从长字符串文本中拆分数据,然后更新每个数据

Sql server 从长字符串文本中拆分数据,然后更新每个数据,sql-server,tsql,Sql Server,Tsql,我试图在ms sql数据库中创建一个有点复杂的存储过程。我主要关注的是输入长字符串文本,然后按字符分割数据,并在匹配的地方更新数据。详细说明:DataString是输入的长文本字符串,它将包含如下示例所示的值 “-”是数据类型名称与其值之间的分隔符 ,“是两种不同类型值之间的分隔符 :”是两组数据之间的分隔符,每组数据由:分隔 现在,您能告诉我如何从长字符串中获取每个数据并将它们插入匹配的位置吗?如果你还需要知道一些事情,可以问这个问题。提前谢谢 长文本字符串示例: ASIN-NsQf8,typ

我试图在ms sql数据库中创建一个有点复杂的存储过程。我主要关注的是输入长字符串文本,然后按字符分割数据,并在匹配的地方更新数据。详细说明:
DataString
是输入的长文本字符串,它将包含如下示例所示的值
“-”
是数据类型名称与其值之间的分隔符
,“
是两种不同类型值之间的分隔符
:”
是两组数据之间的分隔符,每组数据由
分隔
现在,您能告诉我如何从长字符串中获取每个数据并将它们插入匹配的位置吗?如果你还需要知道一些事情,可以问这个问题。提前谢谢

长文本字符串示例:

ASIN-NsQf8,type-0,Price-7,IsPrime-1:ASIN-fD5tsQ,type-1,Price-13,IsPrime-0:ASIN-tvQtsu,type-1,Price-14,IsPrime-1
未完成的SQL代码:

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
不幸的是,string_split()不返回序列号。因此,如果您愿意使用另一种同样有效的拆分/解析函数

注意:我对try\u convert()部分做了假设

示例

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]
如果有助于可视化,子查询将返回

ASIN    Type    Price   IsPrime
tvQtsu  1       14.00   1
NsQf8   0       7.00    1
fD5tsQ  1       13.00   0
TVF如果感兴趣

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)
);

您使用的是哪种数据库管理系统?(该代码是特定于产品的。)MS SQL management studio当前版本version@jarlh
dbo
VARCHAR(MAX)
sqlserver的味道。您使用的是什么版本的SQL Server?是的,它是MS SQL Server 2017 express editionMsg 208,级别16,状态1,第16行无效的对象名称“dbo.tvf Str Parse”。@johnCogdle您需要添加该函数provided@johnCogdle添加了2016+方法的子查询是的,这很有效!但是你能告诉我为什么我会收到这样的消息吗?警告:空值被聚合或其他集合操作消除。@johnCogdle你可以添加集合ANSI_警告,或者用。。。否则“。。。例如然后B.RetVal else“”结束
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