2016-12-14 7 views
1

Я пытаюсь использовать подготовленныеStatement для данных INSERT, только если они не существуют в моей базе данных, но я получаю сообщение об ошибке.sqlPreparedStatement: INSERT INTO, если не существует

#1064 - Erreur de syntaxe près de 'INTO `test` (`id_test`, `name`) VALUES ("1", "TEST")' à la ligne 1 

Код:

SET @preparedStatement = INSERT INTO `test` (`id_test`, `name`) VALUES ("1", "TEST"); 
PREPARE alterIfNotExists FROM @preparedStatement; 
EXECUTE alterIfNotExists; 
DEALLOCATE PREPARE alterIfNotExists; 

Дез

+0

Tag СУБД вы используете. (Ответ может зависеть от используемого продукта.) – jarlh

+0

Синтаксис должен работать на mysql и postgresql – wawanopoulos

+1

Я не думаю, что Postgresql отлично справляется с этими обратными тиками. И, вероятно, хочет одинарные кавычки для литералов. (Путь ANSI SQL.) – jarlh

ответ

1

Прежде всего, операторы SQL PREPARE/EXECUTE имеют различный синтаксис в MySQL и PostgreSQL. Они несовместимы.

MySQL:

SET @preparedStatement = 
    'INSERT INTO test (id_test, name, other) VALUES (''1'', ''TEST'', ?)'; 
PREPARE alterIfNotExists FROM @preparedStatement; 
SET @other = 'STRING' 
EXECUTE alterIfNotExists USING @other; 
DEALLOCATE PREPARE alterIfNotExists; 

PostgreSQL:

PREPARE alterIfNotExists(text) AS 
    INSERT INTO test (id_test, name, other) VALUES ('1', 'TEST', $1); 
EXECUTE alterIfNotExists('STRING'); 
DEALLOCATE PREPARE alterIfNotExists; 

Есть интерфейсы API для параметризованных запросов на любом языке, и они будут более вероятно, будут совместимы между MySQL и PostgreSQL. Например, в PHP с PDO, использование является одинаковым для обеих баз данных (и других):

<?php 

$stmt = $pdo->prepare(
    "INSERT INTO test (id_test, name, other) VALUES ('1', 'TEST', ?)"); 
$stmt->execute(["STRING"]); 

Для другой части вашего вопроса, воздержаться от вставки, если данные уже есть, это также обрабатывается по-разному между MySQL и PostgreSQL.

MySQL:

INSERT IGNORE INTO ... 

Это будет просто пропустить вставку, если вставка может привести к какой-либо ошибки.

В качестве альтернативы вы можете изменить строку на текущие значения, если строка существует со значениями в уникальных столбцах ключа.

INSERT INTO test (id_test, name, other) VALUES ('1', 'TEST', ?) 
ON DUPLICATE KEY UPDATE name=VALUES(name), other=VALUES(other); 

PostgreSQL:

INSERT INTO test (id_test, name, other) VALUES ('1', 'TEST', ?) 
ON CONFLICT DO NOTHING; 

или:

INSERT INTO test (id_test, name, other) VALUES ('1', 'TEST', ?) 
ON CONFLICT DO UPDATE SET ... 

См https://www.postgresql.org/docs/current/static/sql-insert.html#SQL-ON-CONFLICT

Смежные вопросы