如何使用带有 BIT(1) 列的 PDO 准备语句?

Posted

技术标签:

【中文标题】如何使用带有 BIT(1) 列的 PDO 准备语句?【英文标题】:How do you use PDO prepared statements with a BIT(1) column? 【发布时间】:2014-03-10 07:18:54 【问题描述】:

我有一个包含几个BIT(1) 类型列的数据库表。如果我忘记了准备好的语句,我可以很容易地做这样的事情:

UPDATE tablename SET
bit_column_1 = b'1',
bit_column_2 = b'0'

这会很完美。但是,无论我尝试什么,在使用准备好的语句时,该值始终为 '1'。

如果$_POST['bit_col']0,我已经完成了以下操作:

$stmt = $dbh->prepare("UPDATE tablename SET
    bit_col = :bit_col ");
// First attempt
$stmt->bindValue('bit_col', $_POST['bit_col']);
// Second attempt
$stmt->bindValue('bit_col', $_POST['bit_col'], PDO::PARAM_INT);
// Third attempt
$stmt->bindValue('bit_col', "b'$_POST['bit_col']'");

然后我尝试更改准备好的语句以将b 放在那里,但我得到了number of bound variables does not match number of tokens

$stmt = $dbh->prepare("UPDATE tablename SET
    bit_col = b:bit_col ");
$stmt->bindValue('bit_col', $_POST['bit_col']);

$stmt = $dbh->prepare("UPDATE tablename SET
    bit_col = b':bit_col' ");
$stmt->bindValue('bit_col', $_POST['bit_col']);

另外值得一提的是PDO::ATTR_EMULATE_PREPARES 设置为true。将此设置为false 需要我进行大量重构,因为我在不知不觉中管理数据库连接。

所以我的问题是,是否可以在 mysql 中使用带有 BIT 列的预处理语句,如果可以,如何使用?

【问题讨论】:

你可以不带参数试试这个访问***.com/questions/10540483/… 【参考方案1】:

PDO::ATTR_EMULATE_PREPARES 导致 PDO 与 BIT 列的交互略有不同。如果设置为false,您只需照常插入值,MySQL 将在后台进行任何必要的转换:

$stmt = $dbh->prepare("UPDATE tablename SET
    bit_col = ? ");
$stmt->bindValue(1, $_POST['bit_col']);

但是,如果 PDO 正在模拟准备好的语句,则需要在其中放入 b 以某种方式表明它是 BIT 类型。如果你将b 放在绑定参数中,PDO 将转义单引号,你最终会得到类似'b\'0\'' 的东西被发送到MySQL,这显然是行不通的。 b 因此需要在查询中,而不是在绑定参数中。使用命名参数执行此操作会产生上述“绑定变量数与标记数不匹配”错误,因为 PDO 无法识别带有 b 后跟 : 作为命名参数的字符串。但是,当您使用问号参数标记时,PDO 确实将其识别为参数,如下所示:

$stmt = $dbh->prepare("UPDATE tablename SET
    bit_col = b? ");
$stmt->bindValue(1, $_POST['bit_col']);

由于我们最终需要将b'1' 之类的东西发送到MySQL,因此在绑定值时使用PDO::PARAM_INT 将导致查询失败,因为它将变为UPDATE tablename SET bit_col = b1(数字周围没有引号)所以您必须保留数据类型或使用PDO::PARAM_STR

另外请注意,如果模拟准备好的语句被禁用,此查询将失败并出现语法错误,因此很遗憾,查询需要完全不同地完成,具体取决于您是否模拟准备。

【讨论】:

【参考方案2】:

如果我没记错的话,语法应该是:

$stmt->bindValue(':bit_col', $_POST['bit_col']);

引用 :bit_col 来自:

$stmt = $dbh->prepare("UPDATE tablename SET bit_col = :bit_col ");

【讨论】:

如果将PDO::ATTR_EMULATE_PREPARES 设置为false,这可能会起作用,但这是我尝试的第一件事,我在问题中提到了这一点。

以上是关于如何使用带有 BIT(1) 列的 PDO 准备语句?的主要内容,如果未能解决你的问题,请参考以下文章

带有 SQL Server 和准备好的语句的 PHP PDO

带有准备好的语句的 PDO bindParam() 不起作用

带有命名占位符的 PDO 准备好的语句 IN 子句无法按预期工作 [重复]

如何使用准备好的语句将表单数据插入 PDO?

如何使用准备好的 PDO 语句设置 ORDER BY 参数?

如何使用准备好的 PDO 语句设置 ORDER BY 参数?