1

语境:

我正在尝试使用通常的 UPDATE 语法,通过将令牌绑定到数据的 PDO 方法,使用 MySQL 数据库中的一组值来更新记录。

问题:

要更新的字段数是动态的,并根据已发布到页面的数据进行调整。使用 anif(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();       

# 受影响的行?回声 $stmt->rowCount(); // 1 } catch(PDOException $e) { echo 'Error: ' . $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 回答