在T-SQL中,我有一列包含一些文本,其格式如下:
[Key1:Value1:Value2:Value3:Value4:Value5] [Key2:Value1:Value2:Value3:Value4:Value5] [Key3:Value1:Value2:Value3:Value4:Value5]
其中可以有任意数量的括号集,但通常在3到6之间。我正在寻找一种将它们快速格式化为临时表或表变量的方法,以便可以报告数据。例如,我希望表格式为:
|Key|Column 1|Column 2|Column 3|Column 4|Column 5| |Key 1|Value 1|Value 2|Value 3|Value 4|Value 5| |Key 2|Value 1|Value 2|Value 3|Value 4|Value 5| |Key 3|Value 1|Value 2|Value 3|Value 4|Value 5|
我知道这正在推动SQL的发展,应该通过修改应用程序来解决,但我希望T-SQL现在可以做些聪明的事情。
如果您具有最大的列数,则在CROSS APPLY中使用一些XML。
如果未知,则必须进行动态处理。
例子
Declare @YourTable Table ([ID] varchar(50),[SomeCol] varchar(50)) Insert Into @YourTable Values (1,'[Key1:Value1:Value2:Value3:Value4:Value5]') ,(2,'[Key2:Value1:Value2:Value3:Value4:Value5]') ,(3,'[Key3:Value1:Value2:Value3:Value4:Value5]') Select A.ID ,B.* From @YourTable 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(replace(replace(SomeCol,'[',''),']',''),':','</x><x>')+'</x>' as xml) as xDim) as A ) B
退货
ID Pos1 Pos2 Pos3 Pos4 Pos5 Pos6 Pos7 Pos8 Pos9 1 Key1 Value1 Value2 Value3 Value4 Value5 NULL NULL NULL 2 Key2 Value1 Value2 Value3 Value4 Value5 NULL NULL NULL 3 Key3 Value1 Value2 Value3 Value4 Value5 NULL NULL NULL
编辑
我应该添加,这ltrim(rtrim(...))是可选的,而这varchar(max)是我的示范默认值。
ltrim(rtrim(...))
varchar(max)
编辑-以CRLF分隔的一个字符串
Declare @S varchar(max)=' [Key1:Value1:Value2:Value3:Value4:Value5] [Key2:Value1:Value2:Value3:Value4:Value5] [Key3:Value1:Value2:Value3:Value4:Value5] ' Select 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(@S,char(13)+char(10),'</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(replace(replace(RetVal,'[',''),']',''),':','</x><x>')+'</x>' as xml) as xDim) as A ) B Where A.RetVal is not null