Sql-Server
將 SQL Server 查詢轉換為 PostgreSQL
我正在嘗試使用 CTE 或函式將以下 SQL Server T-SQL 塊轉換為與 PostgreSQL 兼容的塊。轉換的問題是我無法弄清楚如何返回最後插入的 id(
scope_identity()
在 SQL Server 中返回標識列中最後插入的 id)。IF ( NOT EXISTS ( SELECT p_id FROM qr_request WHERE q_ota = 'Done' ) ) BEGIN INSERT INTO qr_request ( u_id ,c_id ,r_id ,q_ota ) VALUES ( 1 ,2 ,3 ,'P' ) COMMIT SELECT Scope_Identity() AS id ,p.email AS n FROM person p WHERE p.uid = 33 AND deleted = 0 END ELSE SELECT NULL AS id ,p.email AS n FROM person p WHERE p.uid = 33 AND deleted = 0
任何幫助,將不勝感激。
由於 PostgreSQL 不像 SQL Server 那樣在表上使用相同的傳統“ID”概念,而是使用序列,因此獲取最後一個值有點不同,但有很多方法可以做到這一點,正如在這個精通StackOverflow 的答案中所注意到的那樣.
具體來說,您可以利用的功能是CURRVAL 和 LASTVAL。
來自上述和連結的 StackOverflow 答案的相關資訊:
CURRVAL()
:INSERT INTO persons (lastname,firstname) VALUES ('Smith', 'John'); SELECT currval('persons_id_seq');
必須知道序列的名稱。警告: currval() 僅在同一會話中的 INSERT (已執行 nextval() )之後有效。
LASTVAL()
:這與前麵類似,只是您不需要指定序列名稱:它會查找最近修改的序列(始終在您的會話中,與上述相同的警告。)
由於 SQL(或 Postgres)中沒有 IF,我將重寫它以使用數據修改公用表表達式:
with new_request as ( INSERT INTO qr_request (u_id,c_id,r_id,q_ota) select * from ( VALUES (1,2,3,'P') ) as x(u_id,c_id,r_id,q_ota) where not exists (SELECT p_id FROM qr_request WHERE q_ota = 'Done') returning id --<< returns the generated ID if an INSERT happened ) select nr.id, p.email AS n FROM person p left join new_request nr on true WHERE p.uid = 33 AND deleted = 0 ;
顯然
qr_request.id
必須定義為它在插入期間自動生成一個新值。推薦的方法是使用generated always as identity
. 所以如果你在 SQL Server 中有這個:create table qr_request ( id integer identity primary key u_id integer, c_id integer, r_id integer, q_ota varchar(5) );
您將在 Postgres 中使用以下內容:
create table qr_request ( id integer primary key generated always as identity u_id integer, c_id integer, r_id integer, q_ota varchar(5) );