【T-SQL】將單一欄位組合字串轉成多欄

  • 9740
  • 0
  • SQL
  • 2020-03-03

利用轉型SQLXML進行字串分割

環境:SQL2008 R2

 SQL2016 資料庫已經有 STRING_SPLIT (Transact-SQL) 字串分割函式了,但舊的資料庫還是需要自己寫FUNCTION才能完成分割的動作,這部分網路上有不少前輩已經有寫教學了,很值得參考,

例如:

[SQL] 使用 CTE 拆解逗號相隔的字串為資料列

[MSSQL] 自己寫SQL Server的Split()函數

當初寫程式,用在C#開發,在系統中可以用 split()將資料進行分割,顯示在畫面上,所以就直接將部分資料組合後回寫進資料表的單一欄位做紀錄備查。

沒想到果然遇到需要拿出來用的時候,但是竟然不是使用系統讀取。這次是要將存在欄位中的資料直接產出報表,提供給同仁做查核。

原先就有寫好FUNCTION,將字串分割成一個table後取用,但是這樣的分割並不是我想要的,在查找資料的過程中,看到黑大的文章【】其中有段說明 【在SQL也能將複合字串拆成多欄位囉!(請直接參閱黑大文章)】,直接命中需求。

就利用黑大的說明,進行測試。並將結果記錄下來:

--宣告暫存資料表,並寫入測試資料
declare @t table(id int, date datetime,data varchar(2000))
insert into @t(id,data)
select 23,'<DATA>2,QQPrint,HJ92288,1076-013,381062,10000,G27190.14,1926,TW,2V,CCD37024</DATA>'
insert into @t(id,data)
select 24,'<DATA>2,QQPrint,HJ92288,1076-013,381062,10000,G27190.11/G27190.20,1926/1926,TW,2V,CCD37024</DATA>'

--declare @pKey varchar(2000) 
--SET @pKey = '<DATA>2,QQPrint,HJ92288,1076-013,381062,10000,G27190.14,1926,TW,2V,CCD37024</DATA>'
--select id, convert(xml,  replace(replace(data,'DATA','n'), ',','</n><n>')) as x from @t 
--在字串中,插入</n><n> 轉型成SQLXML型別,就可用.value('(/n)[2]', 'varchar(16)')取出分隔字串,SQL也能將複合字串拆成多欄位

SELECT id,
Keys.x.value('(/n)[2]', 'varchar(20)') AS 設備 ,
Keys.x.value('(/n)[3]', 'varchar(10)') AS 單號,
Keys.x.value('(/n)[4]', 'varchar(10)') AS 品號,
Keys.x.value('(/n)[5]', 'varchar(10)') AS 客戶品號,
Keys.x.value('(/n)[6]', 'int') AS 數量,
Keys.x.value('(/n)[7]', 'varchar(20)') AS 批號,
Keys.x.value('(/n)[8]', 'varchar(10)') AS 日期,
Keys.x.value('(/n)[9]', 'varchar(3)') AS 產地,
Keys.x.value('(/n)[10]', 'varchar(20)')AS 規格,
Keys.x.value('(/n)[11]', 'varchar(16)') AS 品名
 FROM  
(select id, convert(xml,  replace(replace(data,'DATA','n'), ',','</n><n>')) as x from @t ) AS Keys

結果如下:

再來就是跟其他實體資料去 join 取得報表資料即可。

同廠加註:

[SQL]將字串依分隔符號轉成Table

 

後記:使用時頗吃效能,有想要使用的人需要自己注意。

水滴可成涓流,涓流可成湖泊大海。
汲取累積知識,將知識堆積成常識;將常識探究成學識;將學識簡化為知識;授人自省。