简体   繁体   English

使用InnoDB引擎的UPSERT?

[英]UPSERT using InnoDB engine?

Here is the solution for an UPSERT that uses primary key idfill to check for duplicates. 这是使用主键idfill检查重复项的UPSERT的解决方案。 I'm just not sure if it's sql injection proof or even efficient? 我只是不确定它是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);
}

INSERT adds a new row if it can. 如果可以的话,INSERT添加一个新行。

When you use INSERT...ON DUPLICATE KEY UPDATE, it performs an UPDATE only if your INSERT would create a duplicate value in a primary key or unique key column. 当您使用INSERT ... ON DUPLICATE KEY UPDATE时, 当您的INSERT将在主键或唯一键列中创建重复值时,它才执行UPDATE。

Thank you for posting your table definition. 感谢您发布表定义。 I see now that you have no UNIQUE column besides idfill , the primary key. 现在我看到,除了主键idfill之外,您没有UNIQUE列。

So if you don't specify a value for idfill, it'll generate a new value in a new row. 因此,如果您不指定idfill的值,它将在新行中生成一个新值。 There's no way this will trigger the duplicate key. 这根本不可能触发重复密钥。 It makes no sense to run the query as you are doing and not expect it to create a new row. 当您正在执行查询并且不希望其创建新行时,这没有任何意义。

You must specify an existing value in your INSERT statement for a PRIMARY or UNIQUE KEY, in order to cause the INSERT to fail and fall through to do the UPDATE. 您必须在INSERT语句中为PRIMARY或UNIQUE KEY指定一个现有值,以使INSERT失败并失败进行UPDATE。 Otherwise the INSERT will succeed, by creating a new row with a distinct value for the primary key. 否则,INSERT将通过使用主键具有不同值的新行来成功完成。

So you must add the idfill column to your INSERT, and specify a value that conflicts with one already existing in the database. 因此,您必须将idfill列添加到INSERT中,并指定一个与数据库中已经存在的值冲突的值。

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

Apologies that I didn't notice this immediately, but another problem is that the UPDATE part of your statement isn't changing anything . 抱歉,我没有立即注意到这一点,但是另一个问题是,您语句的UPDATE部分没有更改任何内容

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

This sets the columns to exactly the same values they had before. 这会将列设置为与以前完全相同的值。 It's a no-op. 这是没有操作的。 It's the equivalent of doing this in PHP: 这等效于在PHP中执行此操作:

$sql = $sql;

You can work around this by using the VALUES() function to re-use the values you tried to insert. 您可以通过使用VALUES()函数重新使用您尝试插入的值来解决此问题。 Here's an example: 这是一个例子:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM