【问题标题】:Splitting a variable length column in SQL server safely安全地拆分 SQL Server 中的可变长度列
【发布时间】:2013-06-22 13:44:43
【问题描述】:

我在 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”),是否可以通过错误检查有效地做到这一点。

谁能告诉我解决问题的最佳方法?

非常感谢。

【问题讨论】:

  • 行上是否定义了任何 id?

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


【解决方案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

【讨论】:

  • 我的问题是id现在可以有空格,所以可以是“User ID=12323”而不是“UserID=223123”。我在初始 SELECT 的开头添加了一个额外的 REPLACE,将 ' ' 替换为 '',但是我现在收到消息: XML parsing: line 1, character 123, equal expected - 即使它适用于我的小提琴制成;甚至当我在 SQL Server Management Studio 中运行它时,它也会在一秒钟内返回一组值 - 然后显示错误消息。
  • sqlfiddle.com/#!3/d41d8/16255 链接到我正在运行的 SQL 脚本。我在 SQL Server Management Studio 2005 中运行相同的程序,但我一生都无法弄清楚为什么它不会返回任何值。
  • 你能运行 select * cte 并发布你得到的值吗?
【解决方案2】:

假设 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

【讨论】:

    【解决方案3】:

    你可以试试这个拆分功能:http://www.sommarskog.se/arrays-in-sql-2005.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多