Postgresql
對多列使用序列號並從 INSERT 返回
我正在使用
Npgsql
並且我希望能夠執行一個insert
, 和if
語句,該語句將執行一個update
然後返回一個值,因此當ExecuteScalar
被呼叫時它會讀取該值。這在 MSSQL 中做得很好,但我現在正在嘗試支持 PostgreSQL,但我似乎無法做到正確。SQL 與此類似:
insert into mytable (name, uniquecallid) values (@name, @uniquecallid); DO $do$ BEGIN IF coalesce(@UniqueCallId,'') = '' THEN SET @UniqueCallId = coalesce(@CallIdPad, '') || cast(varchar(50), select currval('mytable_id_seq')); UPDATE mytable SET UniqueCallId = @UniqueCallId WHERE Id = select currval('mytable_id_seq'); END IF; END $do$ select currval('mytable_id_seq');
此錯誤與“選擇附近的語法錯誤”有關。
我該怎麼做才能讓它返回插入的最新值?
我相信這是一個 Npgsql 問題,因為在檢查它執行的 SQL 時,參數被替換為值,但
DO
塊沒有代替參數的值。
語法錯誤
錯誤的直接原因:
WHERE id = **select** currval('mytable_id_seq');
語句末尾缺少分號
DO
:... $do$;
更好的查詢
仔細一看,這似乎不是另一種情況
UPSERT
。似乎插入的列之一需要依賴於多個輸入值以及新檢索到的序列 ID 值。試試這個大大簡化的語句:INSERT INTO mytable (id, name, uniquecallid) SELECT t.id , t.name , CASE WHEN t.uniquecallid <> '' THEN t.uniquecallid ELSE COALESCE(t.callidpad, '') || t.id END FROM ( SELECT nextval('mytable_id_seq') AS id , '@name'::text AS name -- provide values here, once , '@UniqueCallId'::text AS uniquecallid , '@CallIdPad'::text AS callidpad ) t RETURNING id;
需要顯式轉換為
text
(或您實際未公開的數據類型)。這相當於提供的程式碼,只是具有合法的語法並且速度更快- 除非有觸發器或您沒有聲明的非標準預設值……
更簡單
currval()
仔細觀察,這可以進一步簡化:
INSERT INTO mytable (name, uniquecallid) SELECT '@name'::text , COALESACE( NULLIF('@UniqueCallId'::text, '') , COALESCE('@CallIdPad'::text, '') || currval('mytable_id_seq')) RETURNING id;
詳細解釋: