如何获得Vertica中最后发布的序列ID?

时间:2018-07-30 15:10:13

标签: sql vertica

背景:我从PostgreSQL迁移到Vertica,发现IDENTITYAUTO_INCREMENT列中存在一些问题。这些问题之一是,vertica无法为IDENTITY列中已有数据的IDENTITY列赋值或更改列。因此,我创建了一个序列并将该列的默认值设置为唯一,以这样做:

SELECT MAX(id_column) FROM MY_SCHEMA.my_table; 

是12345

CREATE SEQUENCE MY_SCHEMA.seq_id_column MINVALUE 12346 CACHE 1; 

ALTER TABLE MY_SCHEMA.my_table 
ALTER COLUMN id_column SET DEFAULT(MY_SCHEMA.seq_id_column.nextval);

ALTER TABLE MY_SCHEMA.log ADD UNIQUE(id_column);

按预期工作。在这种情况下,我已取消激活缓存,就像在单节点安装中一样,并且我希望我的ID列是连续的。但是,在群集安装中这不是一个选择,因为所需的锁定会导致瓶颈。

问题::在具有多个节点的vertica群集中,如何访问会话中最后一个插入的ID(无其他选择)?

例如在postgreSQL中,我可以做类似的事情

INSERT INTO MY_SCHEMA.my_table RETURNING id_column;

在Vertica中不起作用。此外,Vertica的LAST_INSERT_ID()函数不适用于命名序列。我还感到,由于缓存,查询current_value的{​​{1}}可能会给出错误的结果,但是我不确定。

为什么没有其他选择?

据我所知,选择仅会在提交后给出正确的值。由于性能原因,我无法在每次插入后进行提交。

1 个答案:

答案 0 :(得分:1)

LukStorms的评论为我指明了正确的方向。

NEXTVAL()函数(据我所测试)在连续的情况下给出了一个连续的值,即单个会话查询它们。此外,在并发访问时,如果在插入之后发出,CURRVAL将检索缓存的值,该值可以保证是唯一的,但不一定是连续的。由于我从未像在默认子句中那样在其他任何地方调用过NEXTVAL,所以这为我解决了这个问题,尽管在某些情况下,插入之间对NEXTVAL的附加调用会增加序列计数器。

我可以想到的一种情况(以后将进行测试)是将AUTO COMMIT设置为OFF的情况,对于vertica客户端,默认设置为ON驱动程序。

更新:

这似乎在AUTOCOMMITOFF的情况下也可以使用(使用vertica-python客户端驱动程序显示,其中C是连接,cur是光标) :

cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 1
cur.execute("SET SESSION AUTOCOMMIT TO OFF")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT NEXTVAL('my_schema.my_sequence');")
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4

但是,在回滚连接期间,这似乎没有改变。因此发生以下情况:

C.rollback()
cur.execute("SELECT CURRVAL('my_schema.my_sequence');")
cur.fetchall()
--> 4