Проблемы с моей попыткой реализовать UPSERT

У меня возникла эта проблема при проверке условия для обновления таблицы в PostgreSQL. Он должен проверить, загрузил ли пользователь это один раз, и если да, добавить +1 в acessos,

<?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();
}
?>

1 ответ

Решение

Вы ссылаетесь на $arr но это не видно из вашего размещенного кода, где это назначено. В любом случае, если вы хотите увеличить текущее значение acessos на 1, этот подход совершенно небезопасен в многопользовательской среде.

Вы также полностью открыты для внедрения SQL. Вместо этого используйте подготовленные заявления.

В Postgres 9.5 вы даже можете сделать это в одном выражении с новой реализацией UPSERT INSERT ... ON CONFLICT ON ... DO UPDATE - при условии, что есть UNIQUE или же PRIMARY KEY ограничение на (nome, email):

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

Для повторных звонков вы можете использовать pg_prepare а также pg_execute, Для одного звонка pg_query_params:

pg_query_params($sql, array($_POST[nome_download]
                          , $_POST[email_download]
                          , $_POST[estado_download]
                          , $_SESSION[nome_arquivo_download]));
Другие вопросы по тегам