将字符串/ varchar分隔成行以插入到#temp表中

时间:2017-05-16 15:58:27

标签: sql sql-server

我正在尝试创建临时表并从长字符串'!*|*!'插入行。

这就是我所拥有的:

            Declare @value varchar(max) = '70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836092!|!???!*|*!70!|!05/28/2017!|!05/25/2017!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836093!|!???!*|*!70!|!none!|!none!|!ALLERGAN USA, INC.[A475]!|!Y!|!N!|!GERIMEDB0A!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836094!|!???!*|*!' 
            DECLARE @my1 VARCHAR(500)
            DECLARE @my2 VARCHAR(500)
            DECLARE @my3 VARCHAR(500)
            DECLARE @my4 VARCHAR(500)
            DECLARE @my5 VARCHAR(500)
            DECLARE @my6 VARCHAR(500)
            DECLARE @my7 VARCHAR(500)
            DECLARE @my8 VARCHAR(500)

            SELECT @my1 = ltrim(rtrim(xDim.value('/x[1]', 'varchar(max)')))
                ,@my2 = ltrim(rtrim(xDim.value('/x[2]', 'varchar(max)')))
                ,@my3 = ltrim(rtrim(xDim.value('/x[3]', 'varchar(max)')))
                ,@my4 = ltrim(rtrim(xDim.value('/x[4]', 'varchar(max)')))
                ,@my5 = ltrim(rtrim(xDim.value('/x[5]', 'varchar(max)')))
                ,@my6 = ltrim(rtrim(xDim.value('/x[6]', 'varchar(max)')))
                ,@my7 = ltrim(rtrim(xDim.value('/x[7]', 'varchar(max)')))
                ,@my8 = ltrim(rtrim(xDim.value('/x[8]', 'varchar(max)')))
            FROM (
                SELECT Cast('<x>' + replace((
                                SELECT replace(@value, '!*|*!', '§§Split§§') AS [*]
                                FOR XML Path('')
                                ), '§§Split§§', '</x><x>') + '</x>' AS XML) AS xDim
                ) AS A

            SELECT @my1 ...

它有效,但问题在于它只允许有限数量的分隔字符串。我需要无限制,所以我试图将其更改为插入临时表。

            Declare @value varchar(max) = '70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836092!|!???!*|*!70!|!05/28/2017!|!05/25/2017!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836093!|!???!*|*!70!|!none!|!none!|!ALLERGAN USA, INC.[A475]!|!Y!|!N!|!GERIMEDB0A!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836094!|!???!*|*!' 
            DROP TABLE #TempTable
            CREATE TABLE #TempTable ([row] varchar(max))  

            DECLARE @my1 VARCHAR(500)

            SELECT @my1 = ltrim(rtrim(xDim.value('/x[1]', 'varchar(max)')))
            FROM (
                SELECT Cast('<x>' + replace((
                                SELECT replace(@value, '!*|*!', '§§Split§§') AS [*]
                                FOR XML Path('')
                                ), '§§Split§§', '</x><x>') + '</x>' AS XML) AS xDim
                ) AS A

            INSERT INTO #TempTable ([row])
            SELECT @my1
            select * from #TempTable

这,你可能只看到插入1行。我是否会遍历字符串的长度并插入每个分隔符?

1 个答案:

答案 0 :(得分:1)

以下将解析字符串(两次)。首先是行分隔符,然后是列分隔符。

一旦这些数据存在于表中,您就可以根据需要分配变量(如果这真的是您想要的那样)

带有解析UDF的选项1

Declare @value varchar(max) = '70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836092!|!???!*|*!70!|!05/28/2017!|!05/25/2017!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836093!|!???!*|*!70!|!none!|!none!|!ALLERGAN USA, INC.[A475]!|!Y!|!N!|!GERIMEDB0A!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836094!|!???!*|*!' 

Select RowNr=A.RetSeq
      ,B.*
 From  [dbo].[udf-Str-Parse](@value,'!*|*!') A
 Cross Apply [dbo].[udf-Str-Parse](A.RetVal,'!|!')  B

选项2没有解析UDF

Declare @value varchar(max) = '70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836092!|!???!*|*!70!|!05/28/2017!|!05/25/2017!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836093!|!???!*|*!70!|!none!|!none!|!ALLERGAN USA, INC.[A475]!|!Y!|!N!|!GERIMEDB0A!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836094!|!???!*|*!' 

Select RowNr=A.RetSeq
      ,B.*
 From  (
        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(@value,'!*|*!','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
        Cross Apply x.nodes('x') AS B(i)
       ) A
 Cross Apply (
                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(A.RetVal,'!|!','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
                Cross Apply x.nodes('x') AS B(i)
             )  B

返回

enter image description here

感兴趣的UDF

CREATE FUNCTION [dbo].[udf-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)
);
--Thanks Shnugo for making this XML safe
--Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
--Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
--Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')
  

编辑 - 两种技术的结合

Declare @value varchar(max) = '70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836092!|!???!*|*!70!|!05/28/2017!|!05/25/2017!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836093!|!???!*|*!70!|!none!|!none!|!ALLERGAN USA, INC.[A475]!|!Y!|!N!|!GERIMEDB0A!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836095!|!???!*|*!70!|!none!|!none!|!J500!|!JOHNSON & JOHNSON HEALTHCARE SYSTEM!|!N!|!77836094!|!???!*|*!' 

Select RowNr=A.RetSeq
      ,B.*
 From  (
        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(@value,'!*|*!','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
        Cross Apply x.nodes('x') AS B(i)
       ) A
 Cross Apply (
                Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(max)')))
                      ,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(max)')))
                      ,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(max)')))
                      ,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(max)')))
                      ,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(max)')))
                      ,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(max)')))
                      ,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(max)')))
                      ,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(max)')))
                      ,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(max)')))
                From  (Select Cast('<x>' + replace((Select replace(A.RetVal,'!|!','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml) as xDim) as A 
             )  B
 Where A.RetVal is not null

返回 enter image description here

相关问题