2016-12-14 75 views
1

我想使用preparedStatement來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

標籤您正在使用的數據庫管理系統。 (答案可能取決於所使用的產品。) – jarlh

+0

語法應該在mysql和postgresql上工作 – wawanopoulos

+1

我不認爲Postgresql很好地處理了這些back-ticks。並且可能需要單引號爲文字。 (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