【问题标题】:PDO and CASE statementsPDO 和 CASE 语句
【发布时间】:2016-03-11 13:02:04
【问题描述】:

在我正在构建的应用程序中,我需要检查用户是否填写了他们个人资料中的某些字段,如果没有,则执行操作。

为了查看字段是否填写,我写了以下内容:

$sql = "SELECT count(*) AS userComplete FROM Users 
        WHERE userID = :userID 
        AND userField1 IS NOT NULL
        AND userField2 IS NOT NULL";
$stmt = $this->_db->prepare($sql);
$stmt->bindValue(':userID', $this->_userID, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchColumn(0);    //Returning a single column
$this->_user_profile_complete = $result;

查询返回单列 userComplete。由于 Users 将 userID 作为主键,因此每个 userID 不应超过一个,因此返回的计数为 1 或 0,我可以将其用作真/假。

这行得通,但我很想看看我是否可以 100% 确定我只会得到 1 或 0。所以我修改了我的查询:

$sql = "SELECT CASE WHEN count(*) > 0 THEN 1 
        ELSE CASE WHEN count(*) = 0 THEN 0 
        ELSE 0 END END AS userComplete FROM Users 
        WHERE userID = ':userID' 
        AND userField1 IS NOT NULL
        AND userField2 IS NOT NULL";

使用 CASE 语句将计数与预期值进行比较,我只返回 1 或 0。

当给定用户 ID 并通过 SSMS 直接执行(通过复制查询并将 :userID 替换为实际用户 ID)时,第一个和第二个查询都有效。但是,当通过应用程序运行时,只有第一个查询有效。第二个查询失败并出现以下错误:

'SQLSTATE[IMSSP]: 尝试绑定参数号 0。SQL Server 最多支持 2100 个参数。'

根据堆栈跟踪,当 PDO 尝试执行()时抛出异常。第二个语句导致此错误的原因是什么?

【问题讨论】:

  • 可能是第三行有END END 我不太熟悉 sql 案例,但从健全性检查的角度来看这似乎很奇怪。
  • 选择案例是不必要的。您的第一个查询非常好,并且将优于第二个。
  • @ryantxr 很高兴知道!这比其他任何事情都更有趣 - 我看到了一种不同的方法,并且很好奇它是否会起作用,当它不起作用时会感到困惑。

标签: php sql-server pdo case


【解决方案1】:

为什么需要嵌套的 case 语句?如果计数大于零,则您希望返回 1,否则返回 0。试试这个

$sql = "SELECT CASE WHEN count(*) > 0 THEN 1 
        ELSE 0 END AS userComplete FROM Users 
        WHERE userID = ':userID' 
        AND userField1 IS NOT NULL
        AND userField2 IS NOT NULL";

【讨论】:

  • 这是一个很好的改进,但恐怕会出现同样的错误。
  • @FelixPamittan 我的问题“SQLSTATE[IMSSP]: 尝试绑定参数号 0。SQL Server 最多支持 2100 个参数”结尾引用的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-05
相关资源
最近更新 更多