2014-02-12 48 views
1

我有一个数据库表,有几个BIT(1)类型的列。如果我忘记准备好的陈述,我可以很容易地做这样的事情:您如何使用PDO预处理语句和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列的预准备语句,如果是这样,如何?

+0

你可以试试这个不带参数
访问http://计算器.com/questions/10540483/pdostatement-mysql-insertion-value-0-into-a-bit1-field-1-written-1/34578200#34578200 – saeed

回答

2

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

另请注意,如果禁用模拟预准备语句,则此查询将失败,并出现语法错误,因此不幸的是,查询需要根据是否正在模拟准备而完全不同。

0

如果我没有记错的话,语法应为:

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

引用:bit_col来自:

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

如果将'PDO :: ATTR_EMULATE_PREPARES'设置为“假”,但那是我尝试的第一件事,我在我的问题中提到过。 – Mike