【问题标题】:Sybase - Use parameter for IN clauseSybase - 使用 IN 子句的参数
【发布时间】:2013-02-07 07:19:24
【问题描述】:

我需要一种在 Sybase 中执行以下模式的方法:

SELECT * FROM tbl WHERE x IN (@list)

选择将是存储过程的一部分,它从 Web 表单传递值。我想允许用户为每个字段输入 0 到多个搜索键,其中输入的多个值由某个分隔符分隔。目前我可以处理 0 到 1 个键,但不能处理 >1。

我一直在尝试为这个类似于上面的伪 SQL 找到一个优雅的解决方案,虽然我发现其他数据库似乎有内置的方式来支持(例如数组),但它似乎不存在是 Sybase 的简单答案。

任何帮助将不胜感激。如果更多详细信息有帮助,请告诉我。

【问题讨论】:

  • 优雅的解决方案是采用数组或 CTE 的数据库。没有他们,这将有高跷醉大象的优雅。您可以将逗号分隔的值作为参数传递,然后将其拆分到临时表中并使用 join 而不是 in。
  • 不幸的是,我受困于我们现有的技术堆栈。我认为将字符串切分到临时表中可能是最可靠的方法,尽管那样会很糟糕。
  • 至少隐藏了前端代码中的乱七八糟,万一出错了还可以怪DBA。 :)

标签: sql stored-procedures parameters sybase optional-parameters


【解决方案1】:

您可以使用 sub select 和 sa_split_list 系统过程将列表拆分为单独的值。

摘自documentation

CREATE PROCEDURE ProductsWithColor( IN color_list LONG VARCHAR )
BEGIN
  SELECT Name, Description, Size, Color
  FROM Products
  WHERE Color IN ( SELECT row_value FROM sa_split_list( color_list ) )
END;
go

SELECT * from ProductsWithColor( 'white,black' );

或者使用INNER JOIN代替WHERE进行过滤

  SELECT Name, Description, Size, Color
  FROM Products
  INNER JOIN sa_split_list( color_list ) FILTER ON FILTER.row_value = Products.Color

【讨论】:

    【解决方案2】:

    不确定是否为时已晚,但这是我在遇到类似用例时发现的,它确实对我有帮助。

    [1]: https://stackoverflow.com/questions/11101106/sybase-use-parameter-as-where-clause

    干杯

    【讨论】:

      【解决方案3】:

      试试这个方法:

      declare @list varchar(100)
      
      select @list = '1,2,3,4,5'
      
      exec('SELECT * FROM tbl WHERE x IN ('+@list+')')
      

      【讨论】:

        【解决方案4】:

        我刚刚用php和mysql回答了一个非常相似的问题,但我觉得答案在这里同样适用,所以我将其复制/粘贴。

        我只是在 Visual Studio 中处理了同样的问题。首先,我创建了一串参数以添加到 SQL 语句中。您只需要处理问号 (?),我所做的很多事情都超出了您的需要:

        string[] inClause = new string[keywordTerms.Length];
        
        for (int i = 0; i < keywordTerms.Length; i++)
            inClause[i] = ":keyword" + i.ToString("00");
        

        然后在创建我的选择时,我将以下内容放入:

        sqlStatement += "WHERE kw.keyword IN (" + String.Join(", ", inClause) + ")"
        

        最后,我在这段代码中添加了参数:

        for (int i = 0; i < keywordTerms.Length; i++)
            cmd.Parameters.Add(inClause[i], OracleDbType.Varchar2, 20, "keyword").Value = keywordTerms[i];
        

        希望有帮助!

        【讨论】:

          【解决方案5】:

          您不能在 SQL 中真正做到这一点。最好的选择是进行字符串比较:

          select *
          from tbl
          where ','+@list+',' like '%,'+x+',%'
          

          或者,如果您将语句创建为动态 SQL,那么您可以将列表合并到 SQL 查询字符串中。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2016-05-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-09-25
            相关资源
            最近更新 更多