窗口函数中的 SETVAL

joy*_*eak 3 postgresql sequence postgresql-9.2

我正在尝试使用相同的键字段对多个表执行 INSERT。根据序列操作函数

重要提示:由于序列是非事务性的,如果事务回滚,则 setval 所做的更改不会撤消。

以上让我担心在我的交易过程中其他东西可能会更新序列。

所以这是我当前的查询:

BEGIN;
--[other queries and stuff here]
CREATE TEMPORARY TABLE my_temp_table ON COMMIT DROP AS
SELECT
    (SETVAL('seq_A',(SELECT "last_value" FROM seq_A) + COUNT(*) OVER ()) - (ROW_NUMBER() OVER (ORDER BY some_other_table.field1 DESC))) AS primarykeyid,
    some_other_table.morefields
FROM
    some_other_table;
--[INSERTs into multiple different tables with primarykeyid here]
COMMIT;
Run Code Online (Sandbox Code Playgroud)

是否SETVAL被调用一次中的每一行my_temp_table或者它被调用一次?

在创建之前进行单独的查询以my_temp_table在运行之前“保留”值会更好吗?例如:

BEGIN;
--[other queries and stuff here]

CREATE TEMPORARY TABLE my_temp_sequence_value ON COMMIT DROP AS
SELECT
    (SETVAL('seq_A',(SELECT "last_value" FROM seq_A) + COUNT(*)) AS seq_val
FROM
    some_other_table;

CREATE TEMPORARY TABLE my_temp_table ON COMMIT DROP AS
SELECT
    (SELECT seq_val FROM my_temp_sequence_value) - (ROW_NUMBER() OVER (ORDER BY some_other_table.field1 DESC))) AS primarykeyid,
    some_other_table.morefields
FROM
    some_other_table;
--[INSERTs into multiple different tables with primarykeyid here]
COMMIT;
Run Code Online (Sandbox Code Playgroud)

dez*_*zso 5

您使用的setval()不是人们通常所期望的。它用于重置序列。向 ID 和其他内容提供新值是由nextval(). 它的功能是这样描述的

nextval() 推进序列并返回新值

重要的是要注意,这样做是为了使两个并发事务在调用nextval(). 此外,它并不真正适合制作无间隙系列 - 您的问题中已经引用了原因。