Sql 同一插入过程中另一列中串行列的参考值
我有一个带有串行主键的表,还有一个ltree列,我希望它的值是这些主键的串联。e、 gSql 同一插入过程中另一列中串行列的参考值,sql,postgresql,auto-increment,sql-insert,Sql,Postgresql,Auto Increment,Sql Insert,我有一个带有串行主键的表,还有一个ltree列,我希望它的值是这些主键的串联。e、 g id | path ---------- 1 1 2 1.2 3 1.2.3 4 1.4 5 1.5 我很好奇是否有一种方法可以在一个查询中进行这样的插入,例如 INSERT INTO foo (id, ltree) VALUES (DEFAULT, THIS.id::text) 我可能在这里做得太过分了,试图在一个查询中完成我应该在两个查询中完成的操作(分组在一个事务中)。
id | path
----------
1 1
2 1.2
3 1.2.3
4 1.4
5 1.5
我很好奇是否有一种方法可以在一个查询中进行这样的插入,例如
INSERT INTO foo (id, ltree) VALUES (DEFAULT, THIS.id::text)
我可能在这里做得太过分了,试图在一个查询中完成我应该在两个查询中完成的操作(分组在一个事务中)。这在我的测试中起到了作用:
INSERT INTO foo (id, ltree) VALUES (DEFAULT, (SELECT last_value from foo_id_seq));
我认为如果两个插入同时发生,则存在竞争条件,因为这引用的是最后一个序列值,而不是当前行。我个人更倾向于这样做(伪代码):
您可以使用CTE从序列中检索一次值,然后重复使用: 该课程要求博士后9.1或更高版本 如果您不确定序列的名称,请使用 相反: 如果表名“foo”在数据库中的所有模式中可能都不是唯一的,那么请对其进行模式限定。如果任何名称的拼写不标准,则必须使用双引号:
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
使用指示的快速测试也可能有效:
INSERT INTO foo (ltree) VALUES ('1.' || lastval());
- 您只需将
保留在查询之外,即可自动分配id
列。没什么区别serial
- 行之间不应该存在争用条件。一:
currval
返回当前会话中此序列的nextval
最近获取的值。(如果nextval
出现错误,则会报告错误。)
此会话中从未为此序列调用过。)因为这是
返回一个会话本地值,它给出了一个可预测的答案
或者自当前会话以来,其他会话未执行nextval
确实如此。
此功能需要序列上的用法
或选择
权限
lastval
返回当前会话中由nextval
最近返回的值。此函数与当前值相同,不同之处在于
将序列名称作为它引用的参数
序列nextval
最近在当前会话中应用于。
如果尚未调用nextval
,则调用lastval
是错误的
本届会议
此功能需要上次使用序列的用法
或选择
权限
我的
但是,毕竟它可能会失败:无法保证在调用
lastval()
填充第二列ltree
之前填充默认值(并在过程中调用nextval()
)。因此,请坚持使用第一种解决方案,并确保nextval()
。该路径看起来不太可查询。我的路径值基于此:PostgreSQL具有递归、通用表表达式,比路径解决方案/解决方案简单且快速。是否保证nextval()
将首先被调用以查找下一个主键,以便lastval()
不会引发错误?您的第二个建议引发了55000个错误:在PostgreSQL 9.5上,此会话中尚未定义lastval。@Bernard:谢谢您的纠正,我相应地更新了。添加了一种在不知道序列名称的情况下执行的方法。
WITH i AS (
SELECT nextval(pg_get_serial_sequence('foo', 'id')) AS id
)
INSERT INTO foo (id, ltree)
SELECT id, '1.' || id
FROM i;
pg_get_serial_sequence('"My_odd_Schema".foo', 'id')
INSERT INTO foo (ltree) VALUES ('1.' || lastval());