Postgresql
插入或選擇後返回id
我想建構一個函式,如果表中不存在電子郵件值並返回該
email_id
行的值,該函式將插入電子郵件。我怎樣才能做到這一點?另外,如果未插入電子郵件並且它已經存在於數據庫中,我該如何返回該 ID?我需要執行另一個
SELECT
嗎?BEGIN; LOCK TABLE mailing_list IN SHARE ROW EXCLUSIVE MODE; INSERT INTO mailing_list (email) SELECT 'email' WHERE NOT EXISTS ( SELECT * FROM mailing_list WHERE email='email' ); COMMIT;
我已經嘗試添加,
returning id
但它不起作用。我有:查詢沒有結果數據的目的地
@a_horse 已經解釋瞭如何避免您看到的錯誤消息。
這是我們一直在參考的相關版本的一個簡單變體:
CREATE OR REPLACE FUNCTION f_email_insel(_email text, OUT email_id int) AS $func$ BEGIN LOOP BEGIN -- start inner block inside loop to handle possible exception SELECT INTO email_id m.email_id FROM mailing_list m WHERE m.email = _email; IF NOT FOUND THEN INSERT INTO mailing_list (email) VALUES (_email) RETURNING mailing_list.email_id INTO email_id; END IF; EXCEPTION WHEN UNIQUE_VIOLATION THEN -- inserted in concurrent session. RAISE NOTICE 'It actually happened!'; -- hardly ever happens END; EXIT WHEN email_id IS NOT NULL; -- else keep looping END LOOP; END $func$ LANGUAGE plpgsql;
您只需要循環來處理可能的競爭條件:如果並發事務在and
SELECT``INSERT``UNIQUE``UNIQUE``email
具有 CTE的替代方案作為一條SQL 語句執行。所以這裡的成本略小(更簡單的查詢),但競爭條件的時間框架略大。特別是如果該行經常已經存在,這會更快一些。
閱讀那裡的詳細說明,然後選擇最適合您的案例的方法。