在SQL Server中安全地拆分可变长度列

时间:2013-06-25 16:34:07

标签: sql sql-server regex sql-server-2005 select

我在SQL表中有以下表格的列(varchar400):

Info
UserID=1123456,ItemID=6685642

该列是通过我们的销售点应用程序创建的,因此我无法正常将其分成两列,因为这会导致大量工作。我的问题是这个列用于存储我们数据库中产品的属性,所以虽然我只关心UserID和ItemID,但这里可能存在多余的信息,例如:

   Info
   IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.

我想要检索的只是两列,如果Info列中不存在这些属性,则不会给出错误。 :

UserID ItemID
123124 1213124

可以通过错误检查有效地执行此操作,因为ID的长度都是可变的,但所有属性都以逗号分隔并遵循统一样式(即“UserID = number”)。

有人能告诉我处理问题的最佳方法吗?

非常感谢。

3 个答案:

答案 0 :(得分:1)

您可以尝试使用此分割功能:http://www.sommarskog.se/arrays-in-sql-2005.html

答案 1 :(得分:1)

试试这个

declare @infotable table (info varchar(4000))
insert into @infotable
select 'IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.'
union all 
select 'UserID=1123456,ItemID=6685642'

-- convert info column to xml type
; with cte as
(
    select cast('<info ' + REPLACE(REPLACE(REPLACE(info,',', '" '),'=','="'),'.','') + '" />' as XML) info,
    ROW_NUMBER() over (order by info) id
    from @infotable
)
select userId, ItemId from 
(

       select T.N.value('local-name(.)', 'varchar(max)') as Name,
       T.N.value('.', 'varchar(max)') as Value, id
       from cte cross apply info.nodes('//@*') as T(N)
) v
pivot (max(value) for Name in ([UserID], [ItemId])) p

SQL DEMO

答案 2 :(得分:0)

假设ItemID = 1213124。以点结束。

Declare @t Table (a varchar(400))
insert into @t values ('IrrelevantID=666,UserID=123124,AnotherIrrelevantID=1232342,ItemID=1213124.')
insert into @t values ('IrrelevantID=333,UserID=222222,AnotherIrrelevantID=0,ItemID=111.')

Select 
STUFF(
Stuff(a,1,CHARINDEX(',UserID=',a) + Len(',UserID=')-1 ,'' )
,CharIndex
(',',
Stuff(a,1,CHARINDEX(',UserID=',a) + Len(',UserID=')-1 ,'' )
) 
,400,'') as UserID

,
STUFF(
Stuff(a,1,CHARINDEX(',ItemID=',a) + Len(',ItemID=')-1 ,'' )
,CharIndex
('.',
Stuff(a,1,CHARINDEX(',ItemID=',a) + Len(',ItemID=')-1,'' )
) 
,400,'') as ItemID
from @t