Postgresql

對多列使用序列號並從 INSERT 返回

  • September 24, 2014

我正在使用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;

詳細解釋:

引用自:https://dba.stackexchange.com/questions/76882