2009-09-08 27 views
90

私はこのコードを使用していると私は不満を超えてよ: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, '',それらのすべてはこのエラーを失敗し、スロー:

Fatal error: Cannot pass parameter 2 by reference in /opt/...

答えて

116

は、私はちょうどPDOを学んでいるが、私は考えますあなたはbindParamが参照するために、変数を取り、bindParamを呼び出した時に値を引っ張っていない

bindParambindValueを使用する必要はありません。私はこれをphp docsのコメントで見つけました:

bindValue(':param', null, PDO::PARAM_INT); 

EDIT:P.S. (あなたが報告のためにシェーバーウィル感謝。)

+0

私はこれらの2つの違いはわかりませんが、いくつか調査します。おかげさまで、あなたの答えも素晴らしかったです。 – Nacho

+3

これは私より良い答えかもしれないと思います(実際に動作する場合) –

+0

PHP 5.3.8 + Mysqlに関する私のテストは、2つの間で生成されたクエリに違いがないことを示しています。重要な部分は、渡された値がNULLであり、 ''または '0'ではないようです。 – Odin

42

bindParam()を使用するときは、変数に渡す必要があります、ありません定数。だから、その行の前に、あなたがしようとした場合には、変数を作成し、それにnull

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

あなたは、同じエラーメッセージが出ます設定する必要があります。

$stmt->bindParam(':v1', 5, PDO::PARAM_NULL); 
+0

あなたはそれを得て、私は自分のコードで前にそれを行ったことに気付いただけです。$ null = PDO :: PARAM_NULL;ありがとう。 – Nacho

+1

この場合、プレースホルダを作成する場合は、bindValue()を使用する方がよいでしょう。 bindParam()はもともとはクエリを実行してから変数を変更し、パラメータを再度バインドせずに再実行するためのものです。 bindValue()は即座にバインドされ、bindParam()はexecute時にのみバインドされます。 –

+0

$ myNull = null行でnullが小文字でなければならないことがわかりました。 $ myNull = NULLは機能しませんでした。 – raphael75

24

INTEGER列を使用してMySQLに(つまり、NULLをすることができます)あなたはこのbindValue(':param', null, PDO::PARAM_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 

は、MySQL 5.5.15でこれをしようとしましたPHP 5.4.1

+0

$ stmt-> execute(array( ':param' =>!空($ val)?$ val:null )); 空文字列の場合は、データベースにNULLを設定したいので、空文字列を使用してください。 –

+0

@ShehzadNizamaniこの例のように、列型が整数の場合のみです。しかし、それ以外の場合は、 'isset()'は 'NULL'との相関が良くなります。空文字列も値です。 – StanE

5

でまだ問題を抱えている人のために(参照によってパラメータ2を渡すことはできません)、PDOにヌル値を渡すだけでなく、null値を持つ変数を定義します。

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

これが役立つことを願っています。

3

あなたはvalueemptyまたは''である場合にのみ、NULLを挿入し、それが利用可能になったとき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フィールドに何も入力しない場合、その後、$productNameSETが、EMPTYになります。したがって、それがempty()であるかどうかを確認し、そうであれば、NULLを挿入します。 PHP 5.5.17

幸運でテスト

+1

あるいは、クエリ文字列でMySQLの 'IFNULL()'関数を使うことができます。このように: '$ sql =" INSERT INTO products(productId、productName)、VALUES(IFNULL(:productId、NULL)、IFNULL(:productName、NULL)) "; ' – starleaf1

+0

私はあなたの解決策が好きです。私はちょうどそれをテストしましたが、残念ながら、ユーザーが入力に何も書いていないときにNULLの代わりに空の文字列を挿入します。それは好みの問題ですが、空の文字列の代わりにNULLを使用しています。 –

6

私は同じ問題を抱えていたと私は、このソリューションはbindParamでの作業が見つかりました:

bindParam(':param', $myvar = NULL, PDO::PARAM_INT); 
-1

はこれを試してみてください。

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

このような古い質問に答える前に、まず他の回答を読むべきです。既に答えられているかもしれません。 –

関連する問題