1

コンテクスト:

トークンをデータにバインドするPDOメソッドを介して、通常のUPDATE構文を使用して、MySQLデータベースの値のセットでレコードを更新しようとしています。

問題:

更新されるフィールドの数は動的であり、ページにPOSTされたデータに応じて調整されます。を使用して、if(isset($_POST[]))すでにデータが含まれている可能性のあるフィールドへの更新を除外しますが、空のデータで上書きされたくありません。

これは、作成するトークンの数が異なることを意味しますが、データをトークンにバインドするための構文は静的であり、調整方法がわかりません。

もちろん、これは次の結果になります。SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens

私のコード:

$ dataは、データベース内のすべての列名の配列であることに注意してください。これは、投稿される可能性のある変数の名前属性のセットでもあります。たとえば、$ _ POST [x]は、指定されたレコードの列xに更新され、xは$dataのメンバーです。

$sql_b =    "UPDATE `temp_data` SET ";  
            foreach($data as $value)
            {
            if(isset($_POST[$value]))
            $sql_b .="$value = :$value, ";
            }

            $sql_b = rtrim($sql_b,', ');    
            $sql_b .=" WHERE UID = '$uid'";

try     
{
$pdo = new PDO('mysql:host=localhost; dbname=db01', $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);   
$stmt = $pdo->prepare($sql_b);

foreach($data as $value)
{
$stmt->bindParam(":$value", $_POST[$value]);
}

$stmt->bindParam(":sv_215_hidden", $_POST[sv_215_hidden]);
$stmt->bindParam(":sv_216_hidden", $_POST[sv_216_hidden]);

$stmt->execute();       

#影響を受ける行?echo $ stmt-> rowCount(); // 1} catch(PDOException $ e){echo'エラー:'。$ e-> getMessage(); }

これの問題領域を強調するには:

このコード:

foreach($data as $value)
            {
            if(isset($_POST[$value]))
            $sql_b .="$value = :$value, ";
            }

可能なUPDATEリクエストのサブセットを作成します

このコードは次のとおりです。

foreach($data as $value)
{
$stmt->bindParam(":$value", $_POST[$value]);
}

可能なすべてのトークン間に常にフルセットのバインディングを作成します。

中心的な質問:

更新されるフィールドのみに一致するようにバインディングの数を調整するにはどうすればよいですか?

4

2 に答える 2

1

あなたはすでにそこにいます。SQLステートメントを生成するときに設定されているフィールドを確認しています。

foreach($data as $value)
        {
        if(isset($_POST[$value]))
        $sql_b .="$value = :$value, ";
        }

したがって、呼び出し時にまったく同じロジックを使用できますbindParam()

foreach($data as $value)
        {
        if(isset($_POST[$value]))
        $stmt->bindParam(":$value", $_POST[$value]);
        }
于 2012-11-26T21:12:49.650 に答える
0

私はあなたがいくつかの追加のステップを行う必要があると思います:

$keys = array('foo', 'bar', 'baz', 'foobar');
$updates = array();
$bound = array();
foreach($keys as $key){
    if (isset($_POST[$key])){
        $updates[] = $key . '= :' . $key;
        $bound[':' . $key] = $_POST[$key];
    }
}
$sql = 'UPDATE table SET ' . implode(',', $updates) . ' WHERE etc'; //add your where clause
$stmt = $pdo->prepare($sql);
$stmt->execute($bound); 

つまり、バインドされたパラメーターの配列を、事前に個別にバインドするのではなく、PDOStatement::executeに渡すことができます。上記のようにすることで、バインドされたパラメーターがSQLの内容と一致することを確認します。

于 2012-11-26T21:15:26.327 に答える