如果我創建一個表具有獨特的contraint,例如:如何捕捉唯一約束錯誤在PostgreSQL
CREATE TABLE distributors (
did integer,
name varchar(40) UNIQUE
);
,如果我嘗試輸入與已經存在的名稱的條目會發生什麼。我試圖這樣做,它只是退出而不顯示任何錯誤消息。有沒有辦法檢查一個新條目是否實際插入?
如果我創建一個表具有獨特的contraint,例如:如何捕捉唯一約束錯誤在PostgreSQL
CREATE TABLE distributors (
did integer,
name varchar(40) UNIQUE
);
,如果我嘗試輸入與已經存在的名稱的條目會發生什麼。我試圖這樣做,它只是退出而不顯示任何錯誤消息。有沒有辦法檢查一個新條目是否實際插入?
如果你試圖插入已存在的名稱記錄,您會收到錯誤信息是這樣的:
ERROR: duplicate key value violates unique constraint "distributors_name_key"
DETAIL: Key (name)=(aaa) already exists.
和記錄不會被插入。
如果從全部級別執行此操作,則會拋出類似於此消息的異常。程序員應該如何處理這個異常。
如果您的ID字段是自動生成的(SERIAL或BIGSERIAL),並且您只插入名稱,如果您插入已存在的名稱,則即使未插入任何記錄,ID序列也會增加1。
爲了避免在INSERT之前進行「SELECT」查詢來檢查,它的記錄已經存在。可以做到所有在一個事務中,在僞代碼:
BEGIN TRANSACTION;
int records = SELECT name FROM table WHERE name = 'aaa' FOR UPDATE; //FOR UPDATE to lock the row from being read by other user until transaction finishes.
if (records == 0)
INSERT INTO table VALUES (1, 'aaa');
else
MessageBox.Show("Record already exists");
COMMIT TRANSACCTION;
@ mj82:請注意,上面的代碼有時也會返回唯一的違規行爲。 – 2011-05-02 12:40:18
@depesz:你能準確地說出它會發生什麼情況嗎? – mj82 2011-05-02 12:49:09
@ mj83:如果有人在SELECT完成之後但INSERT執行之前插入一行 – 2011-05-02 12:56:02
如果插入失敗比應該有的錯誤代碼設置的地方,通過您所使用的接口的一些方法可讀 - 更多細節肯定是在文檔到您的訪問庫/模塊。
或者您可以將插入更改爲:
INSERT INTO distributors (did, name) values (...) RETURNING did;
如果它不返回任何東西 - 出現了錯誤。
不會插入任何數據,從數據庫中解釋失敗的方式取決於您使用何種數據訪問它? libpq/odbc等? – 2011-05-02 11:39:11
我正在使用libpq,那會返回什麼? – error 2011-05-02 11:45:27
用PQresultStatus檢查PQExec的結果; http://www.postgresql.org/docs/8.0/static/libpq-exec.html – 2011-05-02 11:50:00