【问题标题】:Spliting a column that is a variable/value pair, and assigning a var in sql拆分作为变量/值对的列,并在 sql 中分配 var
【发布时间】:2012-06-22 14:09:58
【问题描述】:

我有一个类似的查询:

SELECT ...
FROM ...
WHERE .. AND SomeID = @someID

我继承了这个包含一些动态元素的大型存储过程,所以我需要从另一个表的列中获取 someID 的值,即执行查找。

我该怎么做?

另一列看起来像:

TypeValue
'SomeID=1232,OtherID=3383'

某些列 TypeValue 是 VARCHAR(1000),它包含一个逗号分隔的类型和值对字符串。

所以我需要在, 上拆分,然后在= 上拆分,所以以某种方式得到:

SET @SomeID = SELECT TypeValue FROM MyTABLE WHERE ..

我该怎么做?

(注意,这是 sql server 2000)

【问题讨论】:

  • 你能重新构建你的数据模型来避免这种编码吗?
  • 你想分割字符串。查看stackoverflow.com/questions/2647/split-string-in-sql
  • 亲爱的主人,闻起来很臭。变量名称和变量数量是动态的。如果是这样,您将需要使用动态 SQL 来使用变量。如果不是,为什么要将它们存储为逗号分隔的字符串?无论哪种方式...
  • OP 说他继承了这段代码,根据用户的说法,这可能意味着它“多年来一直运行良好”。它是经典的“实体-属性-值”设计,经过扭曲使其更加丑陋。我同意@Norla,需要使用动态 SQL...
  • 我不知道为什么你们认为解析字符串需要动态 SQL。您能否发布一个答案来展示您认为需要的技术?我同意这是一个糟糕的设计,但如果它在 SQL Server 2000 上仍然很有可能是 OP 所坚持的。

标签: sql tsql sql-server-2000


【解决方案1】:

假设您遇到了糟糕的设计,这不需要动态 SQL:

USE tempdb;
GO

CREATE TABLE dbo.foo(ID INT, TypeValue VARCHAR(1000));

INSERT dbo.foo SELECT 1, 'SomeID=1232,OtherID=3383';
INSERT dbo.foo SELECT 2, 'Blat=prong,SomeID=1254';
INSERT dbo.foo SELECT 3, 'Foo=bar,x=23';
INSERT dbo.foo SELECT 4, 'SomeID=767';
INSERT dbo.foo SELECT 5, 'x=y,SomeID=126,OtherID=3383';

SELECT ID, Value = SUBSTRING(TypeValue, 
  CHARINDEX('SomeID', TypeValue) + 7, 
  COALESCE(NULLIF(CHARINDEX(',', SUBSTRING(TypeValue, 
    CHARINDEX('SomeID', TypeValue) + 8, 1000)), 0), 1000))
FROM dbo.foo
WHERE ',' + TypeValue LIKE '%,SomeID=%';

结果:

ID  Value
--- -----
1   1232
2   1254
4   767
5   126

如果你知道你想要哪一行:

DECLARE @ID INT, @Param VARCHAR(32);
SET @ID = 5;
SET @Param = 'SomeID';


DECLARE @val INT;

SELECT @val = SUBSTRING(TypeValue, 
  CHARINDEX(@Param, TypeValue) + LEN(@Param) + 1, 
  COALESCE(NULLIF(CHARINDEX(',', SUBSTRING(TypeValue, 
    CHARINDEX(@Param, TypeValue) + LEN(@Param) + 2, 1000)), 0), 1000))
FROM dbo.foo
WHERE ID = @ID 
AND ',' + TypeValue LIKE '%,' + @Param + '=%';

PRINT @val;

结果:

126

当然,这并不能防止有人将字符串放入 SomeID 值中,因此如果证明是数字,则仅将其转换为 INT 可能更安全。但你明白了。

【讨论】:

    【解决方案2】:

    使用拆分:http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/01/t-sql-split-function.aspx

    DECLARE @Str NVARCHAR(4000)
    SELECT @Str = 'SomeID=1232,OtherID=3383'
    SELECT * into #temp FROM   [dbo].[Split] (@Str, ',') 
    
    select property = (select Data from dbo.Split((select Data from #temp where Id = b.id), '=') where Id = 1),
           value = (select Data from dbo.Split((select Data from #temp where Id = b.id), '=') where Id = 2)
    from #temp b
    

    【讨论】:

      【解决方案3】:
      SELECT [key] = LEFT(s.value, ca.pos - 1),
         [value] = SUBSTRING(s.value, ca.pos + 1, 8000)
      FROM STRING_SPLIT(@activityValue, '|') s
      CROSS APPLY (VALUES(CHARINDEX(':', s.value))) ca(pos);
      

      从这里拉出来:Is it possible to parse key:value pairs in SQL

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-06
        • 2016-06-20
        • 1970-01-01
        相关资源
        最近更新 更多