25

bit(1)フィールドを使用してブール値を格納し、PDOプリペアドステートメントを使用してテーブルに書き込みます。

これはテストテーブルです:

CREATE TABLE IF NOT EXISTS `test` (
  `SomeText` varchar(255) NOT NULL,
  `TestBool` bit(1) NOT NULL DEFAULT b'0'
) ENGINE=MEMORY DEFAULT CHARSET=latin1;

これはテストコードです:

$pdo = new PDO("connection string etc") ;
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (?,?)') ;
$statement->execute(array("TEST",0)) ;

そのコードを実行すると、TestBoolの下に値1の行が表示されます。そして、bindValue()とbindParm()を使用して同じことを行います。(?の代わりに)名前付きプレースホルダーも試してみましたが、同じ結果になりました。

それから私は試しました:

$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES ("TEST",0)') ;
$statement->execute() ;

これは正しく機能しました(TestBoolの値は0です)。SQLをMySQLに直接パンチすることもできます。

1を挿入すると常に機能することに注意してください。

では、なぜプレースホルダーは値0を挿入できないのでしょうか。(そして私は実際にそれをどのように行うのですか?)

4

5 に答える 5

35

BIT 列は mysql のバイナリ型です (ただし、数値型として文書化されていますが、正確にはそうではありません)。クライアント ライブラリに問題があるため、避けることをお勧めします (これは PDO の問題で証明されています)。列のタイプを TINYINT(1) に変更すると、多くの問題を回避できます。

もちろん、TINYINT(1) はすべての行でストレージの全バイトを消費しますが、mysql のドキュメントによると、BIT(1) も同様に消費します。

から: http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html

ビット ストレージの要件は、約 (M+7)/8 バイトであり、BIT(M) 列もバイト アラインされていることを示しています。

また、これを見つけました:https://bugs.php.net/bug.php?id=50757

したがって、次のコードが期待どおりに機能するかどうかを確認できます。

$pdo = new PDO("connection string etc") ;
$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (:someText,:testBool)') ;
$statement->bindValue(':someText', "TEST");
$statement->bindValue(':testBool', 0, PDO::PARAM_INT);
$statement->execute();

PARAM_INT とは異なる型ヒントを試すこともできますが、それでも動作するようになったとしても、TINYINT に変更することをお勧めします。

于 2012-05-10T21:06:52.100 に答える
5

デフォルトでは、pdo は mysql ドライバーの準備済みステートメントを使用しません。バックグラウンドで動的 SQL を作成することにより、それらをエミュレートします。mysql に送信される sql は、'0' のような一重引用符で囲まれた 0 になり、mysql はこれを数値ではなく文字列として解釈します。

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);

これで動作するはずです。また、実際に準備されたステートメントを実際に使用することになります。

于 2012-05-10T19:02:01.303 に答える
4

prepareパラメータに追加するため、パラメータ名の前'に追加するだけですb

$statement = $pdo->prepare('INSERT INTO `test` (SomeText,TestBool) VALUES (?, b?)');
$statement->execute(array("TEST", 1 /* or TRUE */));

:1, 0 またはを使用できますTRUE, FALSE

于 2016-04-21T07:24:57.307 に答える
1

パラメータなしでこれを試すことができます

if($_POST['bool'] == 1)
{
 $bool = "b'1'";
}
else
{
 $bool = "b'0'";
}
$statement = $pdo->prepare("INSERT INTO `test` (SomeText,TestBool) VALUES (?,$bool)") ;
$statement->execute(array("TEST")) ;

そしてセキュリティ問題なし

于 2016-01-03T15:30:21.527 に答える