【问题标题】:CakePHP - Generated query not working correctly with SQL ServerCakePHP - 生成的查询无法与 SQL Server 一起正常工作
【发布时间】:2010-03-10 13:06:14
【问题描述】:

我有一个 CakePHP 应用程序正在从 MySql 移动到 Sql Server。有一个查询似乎没有正确传输:

$this->Model->find('all', array(
        'conditions' => array(
            'Model.column' => array(1, 2, 3)
        )
    )
);

当我将此语法与 mysql 一起使用时,它似乎“解包”了数组 正确,生成的查询类似于

"...WHERE 'Model.column' IN (1, 2, 3)..."

当我使用sql server时,生成的查询是

"...WHERE 'Model.column' IN 'Array'"...

这显然会产生错误。我昨天在 CakePHP Google Group 上发布了这个问题,但没有收到回复,所以我想我会尝试 SO。如果有人有任何想法/建议,我将不胜感激。

【问题讨论】:

    标签: mysql sql-server cakephp


    【解决方案1】:

    生成它的代码在 dbo_source.php(函数 conditionKeysToString)中,虽然特定的数据库驱动程序可以覆盖它,但我从未见过这样做。

    我的系统上有 1.2.5、1.2.6 和 1.3.0-RC1,它们都附加了“IN (”,并且没有任何内容覆盖该功能。没有仅附加“IN”然后决定是否添加的实例是一个数组或标量值。单词 Array 是在字符串上下文中评估数组变量时发生的情况。例如: php -r '$a = array(1,2,3); echo $a;' 将输出 Array .

    检查两者中的 cake/VERSION.txt 文件。如果它们不同,请备份 SQL Server 实例上的 cake 目录并将其替换为 MySQL 中的目录。

    如果它们相同,请尝试转到 cake/libs/model/datasources 目录。希望您拥有 Unix 或 Linux,因为“grep -r ' IN ' *” 将极大地帮助您。否则比较两个 cake 安装之间的 dbo_soures.php 和 dbo/dbo_mssql.php,看看 conditionKeysToString 是否有任何差异。

    最终我会升级到 1.2.6,以便您获得所有修复。

    【讨论】:

    • 只是添加:'Array' 似乎是 PHP 完成的字符串转换的自动数组,这是正确的。如果这样做,它应该抛出一个 NOTICE。这应该帮助找到在哪里进行演员表。
    • 很抱歉我没有说清楚,但是没有两次安装的蛋糕。我的应用程序是使用 MySQL 作为数据库开发的,但现在管理层希望它使用 SQL Server,因此我正在尝试调试生成的查询中的任何不一致之处。我在 linux 机器上使用 1.2.6。我在 cake/libs/model/datasources/dbo/dbo_mssql.php 中没有看到任何会覆盖默认行为的内容,因此我将尝试查找有关演员的确切位置的更多信息。
    • 只是回来看看你是否取得了任何进展。我猜这甚至是同一台机器,所以 PHP 版本是一样的。 PHP 和调试器可能会很痛苦。跟踪代码的一种简单方法是编辑 dbo_mssql.php 并找到: function _execute($sql) { return mssql_query($sql, $this->connection); } 并将其更改为: function _execute($sql) { $this->log(debug_backtrace());返回 mssql_query($sql, $this->connection); } 它会在你的日志中转储大量数据,但你会得到很多状态信息。
    • 很遗憾还没有答案...有空会回复您。
    • 所以我最初的问题有点偏离...生成的查询实际上是 'Where Model.column IS Array' 而不是 '... IN Array ...'
    【解决方案2】:

    尝试将该条件作为字符串传递:

    $this->Model->find('all', array(
            'conditions' => array(
                'Model.column in (1, 2, 3)'
            )
        )
    );
    

    【讨论】:

    • 如果您对 1、2、3 进行硬编码,那很好。如果这些来自用户,那么您就违背了使用 Cake 之类的东西的目的。 RoR、Cake 等的重点是开发人员不必担心注入攻击。
    【解决方案3】:

    试试这样:

    $this->Model->find('all', array(
            'conditions' => array(
                'Model.column' => array(
                    'OR' => array(1, 2, 3)
                )
            )
        )
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 2014-02-01
      • 2015-01-12
      • 2020-10-18
      相关资源
      最近更新 更多