【问题标题】:"SELECT * FROM users WHERE id IN ( )" == FAIL"SELECT * FROM users WHERE id IN ()" == FAIL
【发布时间】:2008-09-23 23:51:14
【问题描述】:

我有一个名为 sqlf() 的函数,它模拟准备好的语句。例如,我可以执行以下操作:

$sql = sqlf("SELECT * FROM Users WHERE name= :1 AND email= :2",'Big "John"','bj@example.com') ;

由于各种原因,我不能使用准备好的语句,但我想效仿它们。我遇到的问题是像

这样的查询 $sql = sqlf("SELECT * FROM Users WHERE id IN (:1)",array(1,2,3) );

我的代码有效,但它因空数组而失败,例如以下引发mysql错误:

SELECT * FROM Users WHERE id IN ();

有人有什么建议吗?我应该如何将空数组转换为可以注入 IN 子句的 sql?替换 NULL 将不起作用。

【问题讨论】:

    标签: php mysql


    【解决方案1】:

    Null 是唯一可以保证不在集合中的值。为什么它不是一个选项?其他任何东西都可以看作是势集的一部分,它们都是值。

    【讨论】:

    • 好吧,我刚试过,它确实有效。 “IN(NULL)”我认为会做与 IS NULL 相同的事情,但它们是不同的。感谢您的回答。
    【解决方案2】:

    我会说传递一个空数组作为 IN() 子句的参数是错误的。调用此函数时,您可以控制查询的语法,因此您还应对输入负责。我建议在调用函数之前检查参数是否为空。

    【讨论】:

      【解决方案3】:

      是否有可能使用 sqlf 检测空数组并将 SQL 更改为没有 IN 子句?

      或者,您可以在将 SQL 传递给“真正的”SQL 执行程序之前对其进行后处理,以便删除“IN ()”部分,尽管您必须使用各种技巧来查看必须删除哪些其他元素这样:

      SELECT * FROM Users WHERE id IN ();
      SELECT * FROM Users WHERE a = 7 AND id IN ();
      SELECT * FROM Users WHERE id IN () OR a = 9;
      

      会变成:

      SELECT * FROM Users;
      SELECT * FROM Users WHERE a = 7;
      SELECT * FROM Users WHERE a = 9;
      

      根据您的 SQL 的复杂性,这可能会变得很棘手 - 您基本上需要一个完整的 SQL 语言解释器。

      【讨论】:

        【解决方案4】:

        如果您的类似准备函数只是将 :1 替换为等效参数,您可以尝试让您的查询包含类似 (':1') 的内容,这样如果 :1 为空,它会解析为 (''),这不会导致解析错误(但是,如果该字段可以具有空白值,则可能会导致不良行为——尽管如果它是 int,这不是问题)。然而,这不是一个非常干净的解决方案,您最好检测数组是否为空,并简单地使用缺少“IN (:1)”组件的替代版本的查询。 (如果这是 WHERE 子句中的唯一逻辑,那么大概您不想选择所有内容,因此您根本不会执行查询。)

        【讨论】:

          【解决方案5】:

          我会使用零,假设您的“id”列是一个自动分配数字的伪键。

          据我所知,大多数品牌的数据库中的自动密钥生成器都是从 1 开始的。这是一个约定,而不是要求(标准 SQL 中没有定义自动编号的字段)。但是这个约定很常见,你可能可以依赖它。

          由于“id”列中可能永远不会出现零,因此当输入数组为空时,您可以在 IN() 谓词中使用此值,并且它永远不会匹配。

          【讨论】:

            【解决方案6】:

            我能想到的唯一方法是让您的 sqlf() 函数扫描以查看特定替换是否在“IN (”之后不久出现,然后如果传递的变量是空数组,则放入一些东西您肯定知道它不会出现在该列中:例如,"m,znmzcb~~1"。这是一个 hack,当然,但它会起作用。

            如果您想更进一步,您是否可以更改您的函数以便有不同类型的替换?看起来您的函数扫描冒号后跟一个数字。为什么不添加另一种类型,比如 @ 后跟一个数字,这对于清空数组来说是很聪明的(这样你就不必扫描和猜测变量是否应该是一个数组)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2017-09-27
              • 2011-04-06
              • 1970-01-01
              • 2012-01-13
              • 1970-01-01
              • 2011-01-27
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多