web-dev-qa-db-ja.com

PDOを使用してNULL値を挿入するにはどうすればよいですか?

私はこのコードを使用していますが、フラストレーションを超えています。

try {
    $dbh = new PDO('mysql:dbname=' . DB . ';Host=' . Host, USER, PASS);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $dbh->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8'");
}
catch(PDOException $e)
{
    ...
}
$stmt = $dbh->prepare('INSERT INTO table(v1, v2, ...) VALUES(:v1, :v2, ...)');
$stmt->bindParam(':v1', PDO::PARAM_NULL); // --> Here's the problem

PDO::PARAM_NULL, null, '',それらはすべて失敗し、このエラーをスローします。

致命的なエラー:/ opt/...の参照によってパラメーター2を渡すことはできません.

102
Nacho

私はただPDOを学んでいますが、bindValueではなくbindParamを使用する必要があると思います

bindParamは、参照する変数を取り、bindParamの呼び出し時に値を取得しません。私はこれをphpドキュメントのコメントで見つけました:

_bindValue(':param', null, PDO::PARAM_INT);
_

編集:P.S.このbindValue(':param', null, PDO::PARAM_NULL);を実行したいと思うかもしれませんが、すべての人にはうまくいきませんでした(報告してくれたWill Shaverに感謝します)。

131
JasonWoof

bindParam()を使用する場合、定数ではなく変数を渡す必要があります。そのため、その行の前に変数を作成し、nullに設定する必要があります

$myNull = null;
$stmt->bindParam(':v1', $myNull, PDO::PARAM_NULL);

試した場合、同じエラーメッセージが表示されます。

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL);
46
Joe Phillips

MySQLでINTEGER列(NULLの場合もあります)を使用する場合、PDOには(私にとって)予期しない動作があります。

$stmt->execute(Array)を使用する場合、リテラルNULLを指定する必要があり、変数参照によってNULLを指定することはできません。したがって、これは機能しません:

// $val is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => $val
));
// will cause the error 'incorrect integer value' when $val == null

しかし、これは動作します:

// $val again is sometimes null, but sometimes an integer
$stmt->execute(array(
    ':param' => isset($val) ? $val : null
));
// no errors, inserts NULL when $val == null, inserts the integer otherwise

PHP 5.4.1でMySQL 5.5.15でこれを試しました

26
ChrisF

それでも問題がある場合(参照によってパラメーター2を渡すことはできません)、PDOにnullを渡すだけでなく、null値で変数を定義します。

bindValue(':param', $n = null, PDO::PARAM_INT);

お役に立てれば。

7
Pedro Guglielmo

私は同じ問題を抱えていて、このソリューションがbindParamで機能していることがわかりました:

    bindParam(':param', $myvar = NULL, PDO::PARAM_INT);
6
user1719210

NULLvalueまたは_''_の場合にのみemptyを挿入し、使用可能な場合はvalueを挿入する場合。

A)POSTメソッドを使用してフォームデータを受信し、それらの値で関数insertを呼び出します。

_insert( $_POST['productId'], // Will be set to NULL if empty    
        $_POST['productName'] ); // Will be to NULL if empty                                
_

B)フィールドがユーザーによって埋められなかったかどうかを評価し、そうであればNULLを挿入します。

_public function insert( $productId, $productName )
{ 
    $sql = "INSERT INTO products (  productId, productName ) 
                VALUES ( :productId, :productName )";

    //IMPORTANT: Repace $db with your PDO instance
    $query = $db->prepare($sql); 

    //Works with INT, FLOAT, ETC.
    $query->bindValue(':productId',  !empty($productId)   ? $productId   : NULL, PDO::PARAM_INT); 

    //Works with strings.
    $query->bindValue(':productName',!empty($productName) ? $productName : NULL, PDO::PARAM_STR);   

    $query->execute();      
}
_

たとえば、ユーザーがフォームのproductNameフィールドに何も入力しない場合、_$productName_はSETですが、EMPTYになります。そのため、それがempty()であるかどうかを確認する必要があり、そうである場合はNULLを挿入します。

テスト済みPHP 5.5.17

幸運を、

3
Arian Acosta

私の場合、私は使用しています:

  • SQLite、

  • 不明な数のフィールドを処理するためのプレースホルダー付きの準備済みステートメント、

  • everythingが文字列であり、NULL値のようなものが存在しないユーザーによって送信されたAJAX要求

  • NULLsは外部キー制約(許容値)に違反しないため、必然的に挿入する必要があります。

今、ユーザーが投稿で送信する:$_POST[field1]value1これは空の文字列にすることができます"" または "null" または "NULL"

最初に声明を発表します。

$stmt = $this->dbh->prepare("INSERT INTO $table ({$sColumns}) VALUES ({$sValues})");

どこ {$sColumns}field1, field2, ...および{$sValues}は私のプレースホルダーです?, ?, ...

次に、$_POST配列内の列名に関連するデータ$valuesandNULLsに置き換えます。

  for($i = 0; $i < \count($values); $i++)
     if((\strtolower($values[$i]) == 'null') || ($values[$i] == ''))
        $values[$i] = null;

今、私は実行することができます:

$stmt->execute($values);

その他のバイパス外部キー制約。

一方、空の文字列の方が意味がある場合は、そのフィールドが外部キーの一部であるかどうかを確認する必要があります(より複雑です)。

0
centurian

これを試して。

$stmt->bindValue(':v1', null, PDO::PARAM_NULL); // --> insert null
0
hector teran