UPSERT使用InnoDB引擎?

时间:2013-10-04 01:27:08

标签: php mysql

以下是使用主键idfill检查重复项的UPSERT的解决方案。我只是不确定它是否是sql注入证明甚至是高效的?

$idq="SELECT idafill FROM afillInfo, actorsInfo
WHERE (actorsInfo.id = afillInfo.id_actor) AND email = '$_SESSION[email]'" or die    (mysql_error());



$sql = "INSERT INTO afillInfo (idfill, agency, agentPhone, afillChoice, id_actor)
VALUES ( ?,?,?,?, ( select id FROM actorsInfo WHERE email = ?))
ON DUPLICATE KEY UPDATE
`id_actor` = VALUES(`id_actor`),
`agency` = VALUES(`agency`),
`agentPhone` = VALUES(`agentPhone`),
`afillChoice` = VALUES(`afillChoice`)
";


if (($stmt = $con->prepare($sql)) === false) {
trigger_error($con->error, E_USER_ERROR);
}

$result= mysqli_query($con, $idq);
$row_number = 1;
while ($row = mysqli_fetch_array($result)) {

$idfill= $row["idafill"];
}

if ($stmt->bind_param("sssss",
$idfill,
$_POST["agency"], $_POST["agentPhone"],
$_POST["afillChoice"], $_SESSION["email"]) === false) {
trigger_error($stmt->error, E_USER_ERROR);
}


if (($stmt->execute()) === false) {
trigger_error($stmt->error, E_USER_ERROR);
}

1 个答案:

答案 0 :(得分:2)

如果可以的话,INSERT会添加一个新行。

当您使用INSERT ... ON DUPLICATE KEY UPDATE时,如果您的INSERT将在主键或唯一键列中创建重复值,它将执行UPDATE

感谢您发布表格定义。我现在看到除idfill(主键)之外没有任何UNIQUE列。

因此,如果您没有为idfill指定值,它将在新行中生成新值。这不会触发重复键。正如您所做的那样运行查询并且不希望它创建新行是没有意义的。

您必须在INSERT语句中为PRIMARY或UNIQUE KEY指定一个现有值,以便使INSERT失败并通过UPDATE进行操作。否则,INSERT将通过创建具有主键的不同值的新行来成功。

因此,您必须将idfill列添加到INSERT,并指定一个与数据库中已存在的值冲突的值。

INSERT INTO afillInfo (idfill, agency, agentPhone, afillChoice, id_actor)
VALUES (?, ?, ?, ?, ( SELECT id FROM actorsInfo WHERE email = ?))
   ...

道歉,我没有立即注意到这一点,但另一个问题是你的陈述的UPDATE部分没有改变任何东西

        ... UPDATE
`id_actor` = `id_actor`,
`agency` = `agency`,
`agentPhone` = `agentPhone`,
`afillChoice` = `afillChoice`

这会将列设置为与之前完全相同的值。这是一个无操作。这相当于在PHP中执行此操作:

$sql = $sql;

您可以使用VALUES()函数重复使用您尝试插入的值来解决此问题。这是一个例子:

        ... UPDATE
`id_actor` = VALUES(`id_actor`),
`agency` = VALUES(`agency`),
`agentPhone` = VALUES(`agentPhone`),
`afillChoice` = VALUES(`afillChoice`)