【问题标题】:Prepared statement giving different results to query in client准备好的语句给出不同的结果以在客户端查询
【发布时间】:2011-08-05 22:03:01
【问题描述】:

更新:如果我停止 WHERE 子句参数化第二个操作数以便 PHP 运行的查询是:

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users,    
5c9_dpd_usergroups_cms WHERE 5c9_dpd_usergroups_cms.id = 5c9_dpd_users.cms_usergroup_id
ORDER BY username asc

返回正确的结果。但是,如果 WHERE 子句是这样参数化的:

WHERE 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc

然后返回不正确的结果;它似乎将参数化参数转换为“5”并返回 ID 为 5 的结果。有谁知道为什么会发生这种情况,或者我如何找到解决方法?谢谢。

原帖:

我创建了一个数据库抽象层,作为我正在编写的更广泛系统的一部分。我目前正在使用它的 MySQL 实现,如果我在控制台中 C+P 应用程序生成的查询正确运行,但在通过 PHP 函数绑定参数等时会产生不正确的结果,则会发生一个非常奇怪的错误。

首先,这是我的数据库架构的相关部分:

在我的数据库类中创建了一些调试输出后,我得到了有关它生成和执行的查询的以下信息(使用stmt::execute)。

SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id,
5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email FROM 5c9_dpd_users, 
5c9_dpd_usergroups_cms WHERE 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc

Array
(
  [0] => i
  [1] => 5c9_dpd_users.cms_usergroup_id
)

上面显示了生成的查询打印到调试页面,然后是占位符参数的值(和类型)。将表/列名放入查询并在控制台中运行它会给我以下正确的输出:

正如您所见,每个 usergroup_id 的 usergroup_name 都不同。但是,下面的代码不起作用:

// I have executed the statement and bound the result up to this point.

self::$stmt->bind_result($test1, $test2, $test3, $test4, $test5);
    while (self::$stmt->fetch()) {
        echo "ID: $test1<br>Username: $test2 <br>Usergroup ID: $test3 Usergroup Name: $test4 <br> Email: $test5<br><br>";
    }

上面的代码稍微简化了一些,但它也很好地说明了问题。如果您检查上述代码的以下输出,您将看到尽管用户组 ID 不同,但用户组名称仍然相同。

ID: 7
Username: ADD 
Usergroup ID: 1 Usergroup Name: se 
Email: test@test.com

ID: 1
Username: New User 
Usergroup ID: 2 Usergroup Name: se 
Email: test@test.com

ID: 4
Username: test user 
Usergroup ID: 1 Usergroup Name: se 
Email: test@test.com

ID: 2
Username: User2 
Usergroup ID: 5 Usergroup Name: se 
Email: p@b.com

ID: 6
Username: username here 
Usergroup ID: 1 Usergroup Name: se 
Email: test@test.com

ID: 5
Username: xyz 
Usergroup ID: 3 Usergroup Name: se 
Email: pete@pete.com

我完全不知所措!我最初认为这是我的数据库抽象类的问题,但我不再那么确定了,因为我基本上已经删除了所有抽象并且仍然遇到问题。我不确定要提供哪些其他信息,但如果您想了解更多详细信息,我会很乐意提供给他们。

【问题讨论】:

    标签: php mysql mysqli prepared-statement abstraction


    【解决方案1】:

    您的查询有问题:

    SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email
    FROM 5c9_dpd_users, 5c9_dpd_usergroups_cms
    WHERE 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc
    

    你永远不会在某些 id 上加入你的表,你应该做这样的事情

    SELECT 5c9_dpd_users.id, 5c9_dpd_users.username, 5c9_dpd_users.cms_usergroup_id, 5c9_dpd_usergroups_cms.usergroup_name, 5c9_dpd_users.email
    FROM 5c9_dpd_users users
    LEFT JOIN 5c9_dpd_usergroups_cms cms ON cms.id = users.cms_usergroup_id
    WHERE 5c9_dpd_usergroups_cms.id = ? ORDER BY username asc
    

    您必须加入您的组表和用户表,请参阅:http://en.wikipedia.org/wiki/Join_%28SQL%29

    【讨论】:

    • 我承认我不擅长 SQL,但我不太了解;我上面显示的查询 - 使用“速记”连接语法 - 在控制台中运行良好。因此,查询本身不会有问题,不是吗?
    • 你想获取所有在 user_group_cms 中指定 id 的用户吗?我可以在控制台中看到您正在执行的请求吗,因为我们在屏幕截图中看不到它
    • 我希望 PHP 执行查询的结果与在 MySQL 控制台中运行查询的结果相同。正如我上面的例子——第二张截图——这是控制台产生的输出,它是正确的。 usergroup_name 与 users 字段中的每个 cms_usergroup_id 一起提供。我以前从未见过查询在 PHP 中的行为与控制台不同!很迷茫。感谢您的回复。
    • 我在控制台执行的请求是如下:SELECT 5c9_dpd_users.id,5c9_dpd_users.username,5c9_dpd_users.cms_usergroup_id,5c9_dpd_usergroups_cms.usergroup_name,5c9_dpd_users.email FROM 5c9_dpd_users,5c9_dpd_usergroups_cms WHERE 5c9_dpd_usergroups_cms.id = 5c9_dpd_users .cms_usergroup_id 按用户名 asc 排序
    • 好吧,为什么你的速记连接有效,我认为你在放置随机值......好吧,你为什么要绑定两个值Array ( [0] =&gt; i [1] =&gt; 5c9_dpd_users.cms_usergroup_id ) 虽然你只有一个?在您的要求中?