我尝试实施 UPSERT 时遇到的问题

Problems with my attempt to implement an UPSERT

我在 PostgreSQL 中检查更新 table 的条件时遇到了这个问题。它必须检查用户是否下载过一次,如果是,在 acessos.

中添加 +1
<?php
$result2 = pg_query("SELECT * from downloads WHERE (nome = $_POST[nome_download] AND email = $_POST[email_download])");
if (pg_num_rows($result2) == 0){
$result = pg_query("INSERT INTO downloads (nome, email, estado, arquivo, acessos) VALUES ('$_POST[nome_download]','$_POST[email_download]','$_POST[estado_download]','$_SESSION[nome_arquivo_download]','1')");
}else{
$arr[acessos] = $arr[acessos] + 1;
$result = pg_query("UPDATE downloads SET acessos = $arr[acessos] WHERE (nome = $_POST[nome_download] AND email = $_POST[email_download])");
}


if (!$result){
echo "Não foi possível realizar o cadastro. Tente fazer o download mais tarde.";
}
else
{
echo "soft_bd";
pg_close();
}
?>

您提到了 $arr,但从您发布的代码中看不出它的分配位置。无论哪种方式,如果您想将 acessos 的当前值增加 1,这种方法在 multi-user 环境中 是完全不安全的 .

您也完全接受 SQL 注入。请改用准备好的语句。

Postgres 9.5 中,您甚至可以在 单个语句 中使用新的UPSERT implementation INSERT ... ON CONFLICT ON ... DO UPDATE - 假设 UNIQUEPRIMARY KEY 约束 (nome, email):

$sql = 'INSERT INTO downloads AS d (nome, email, estado, arquivo, acessos)
        VALUES (, , , , 1)
        ON CONFLICT ON (nome, email) DO UPDATE 
        SET    acessos = EXCLUDED.acessos + 1';

对于重复调用,您可以使用 pg_prepare and pg_execute. For a single call use pg_query_params:

pg_query_params($sql, array($_POST[nome_download]
                          , $_POST[email_download]
                          , $_POST[estado_download]
                          , $_SESSION[nome_arquivo_download]));