【问题标题】:Checking if a value is IN a colon separated column with in a table检查值是否在表中的冒号分隔列中
【发布时间】:2015-11-23 12:51:36
【问题描述】:

我有一个小问题可以在 C# 中轻松解决,但我被要求在 SQL 中解决。

我有一个以 int 作为参数的存储过程,我需要检查该参数是否在数据库中以冒号分隔的列的值内。

(
                                (
                                    gvf_permitted_projects is null
                                ) 
                                or 
                                (   -- @activeProject IN gvf_permitted_projects
                                    -- @activeProject = 11
                                    -- gvf_permitted_projects = '11:17'
                                )
                            )

这是在我的 SELECT 的 where 子句中,我可以在 C# 中以最小的努力做到这一点,但我不太确定如何在这里做到这一点。我需要使用临时表,然后对其进行选择吗?

【问题讨论】:

  • 数据库中的冒号分隔列如何,遵循任何特定顺序。带有大小写的示例输入数据会有所帮助。
  • 您可以使用自定义拆分 T-SQL 函数。签出这个答案stackoverflow.com/questions/10914576/t-sql-split-string
  • 就像在 cmets 中显示的那样,11:17 那里选择的数字只是示例。但我希望它返回 true,因为 11 在 lsit 中
  • 如果我使用了拆分字符串函数?我可以在 where 子句中实现它吗?
  • 我猜这个查询可能会起作用,只需在WHERE 子句中检查相同的内容-PATINDEX('%'+CAST(@activeProject AS VARCHAR(10))+'%',@gvf_permitted_projects)

标签: sql asp.net sql-server parsing


【解决方案1】:

您可以使用 like 运算符进行一些文本操作,尽管这会有点慢,并且无论如何都会首选标准化结构:

':'+@gvf_permitted_projects+':' like '%:'+cast(@activeProject as varchar(20))+':%'

【讨论】:

    【解决方案2】:

    因此,您必须将字符串拆分为列。如果不允许使用函数,可以使用这个:Splitting Delimited Strings Using XML in SQL Server

    快速演示这是如何工作的:

    DECLARE @xml AS XML
        , @str AS VARCHAR(100)
        , @delimiter AS VARCHAR(1)
    
    SET @str = '11:17'
    SET @delimiter = ':'
    SET @xml = cast(('<X>' + replace(@str, @delimiter, '</X><X>') + '</X>') AS XML)
    
    SELECT N.value('.', 'varchar(10)') AS value
    FROM @xml.nodes('X') AS T(N)
    

    它带回了这个:

    ╔═══════╗
    ║ value ║
    ╠═══════╣
    ║    11 ║
    ║    17 ║
    ╚═══════╝
    

    这就是你的 SQL:

    DECLARE @YourTable TABLE
    (
        Id INT
        , gvf_permitted_projects VARCHAR(100)
    );
    
    INSERT INTO @YourTable (Id, gvf_permitted_projects)
    VALUES (1, '11:17')
        , (2, '11:13')
        , (3, '12:17');
    
    SELECT *
    FROM @YourTable AS YT
    CROSS APPLY (
        SELECT CAST(('<X>' + replace(gvf_permitted_projects , ':', '</X><X>') + '</X>') AS XML)
        ) AS V(N)
    WHERE EXISTS (
            SELECT 1
            FROM N.nodes('X') AS T(N)
            WHERE N.value('.', 'INT') = 11
            );
    

    结果如下:

    ╔════╦════════════════════════╦════════════════════╗
    ║ Id ║ gvf_permitted_projects ║         N          ║
    ╠════╬════════════════════════╬════════════════════╣
    ║  1 ║ 11:17                  ║ <X>11</X><X>17</X> ║
    ║  2 ║ 11:13                  ║ <X>11</X><X>13</X> ║
    ╚════╩════════════════════════╩════════════════════╝
    

    不过,我强烈建议您规范化您的数据结构。这只是一种解决方法。

    【讨论】:

      【解决方案3】:

      在这个答案中,我添加了一些可以用 XML 和字符串值做的好技巧:

      https://stackoverflow.com/a/33658220/5089204

      转到“动态输入”部分。希望这会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多