2017-05-16 48 views
-1

我試圖創建一個臨時表並從長字符串'!*|*!'插入行。將字符串/ varchar分隔成插入到#temp表中的行

這是我有:

  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行。行是否遍歷字符串的長度併爲每個定界插入?

+0

您需要爲行分割一次,然後再爲列分割一次。 –

回答

1

以下將解析字符串(兩次)。首先在行分隔符上,然後在列分隔符上。

一旦該數據在一個表中,你可以根據需要分配給變量(如果那是真的,你想要什麼)

選項1與解析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 [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

+0

非常有幫助,並通過答案。謝謝。 –

+0

@DavidTunnell樂於助人。但是看着你的問題,你是否有最大數量的列和無限數量的行?因爲這將是一個小問題樞軸 –

+0

@DavidTunnell見編輯部 –

相關問題