如果我有一个带有自动递增ID列的表,我希望能够在该表中插入一行,并获取我刚刚创建的行的ID。我知道,通常,StackOverflow问题需要某种经过尝试或研究的代码,但是我不确定从Snowflake哪里开始。我已经翻阅了他们的documentation,但对此一无所获。
到目前为止,我能做的最好的尝试是尝试result_scan()
和last_query_id()
,但是这些操作并没有为我提供有关所插入行的任何相关信息,只是确认已插入行。 / p>
我相信我要的是与MS SQL Server的SCOPE_IDENTITY()
函数类似的方法。
MS SQL Server的SCOPE_IDENTITY()
是否具有Snowflake等效功能?
编辑:为了在此处添加代码
CREATE TABLE my_db..my_table
(
ROWID INT IDENTITY(1,1),
some_number INT,
a_time TIMESTAMP_LTZ(9),
b_time TIMESTAMP_LTZ(9),
more_data VARCHAR(10)
);
INSERT INTO my_db..my_table
(
some_number,
a_time,
more_data
)
VALUES
(1, my_time_value, some_data);
我想对我刚刚插入的这一行进行自动递增ROWID
。
答案 0 :(得分:1)
注意:在极少数情况下,下面的答案可能不是100%正确,请参见下面的“更新”部分
雪花今天不提供相当于SCOPE_IDENTITY的内容。
但是,您可以在执行给定语句后立即利用Snowflake的time travel来检索列的最大值。
这是一个例子:
create or replace table x(rid int identity, num int);
insert into x(num) values(7);
insert into x(num) values(9);
-- you can insert rows in a separate transaction now to test it
select max(rid) from x AT(statement=>last_query_id());
----------+
MAX(RID) |
----------+
2 |
----------+
如果以后想访问last_query_id()
,也可以将insert into x(num) values(5);
set qid = last_query_id();
...
select max(rid) from x AT(statement=>$qid);
保存到变量中,例如
rid
注意-通常是正确的,但如果用户例如手动将大值插入Q1
中,这可能会影响此查询的结果。
注意,我意识到上面的代码很少会产生不正确的答案。
由于在像Snowflake这样的分布式系统中查询的各个阶段的执行顺序可以是不确定的,并且Snowflake允许并发INSERT语句,因此可能发生以下情况
Q2
和Q1
进行一个简单的单行INSERT,大约在同一时间开始Q2
开始,领先一步Q1
开始1
从IDENTITY列中创建一个值为Q2
的行2
从IDENTITY列中创建一个值为Q2
的行Q1
领先于Q2
-这是关键部分 T2
提交,在时间Q1
标记为完成T1
提交,在时间T1
标记为完成请注意,T2
晚于SELECT ... AT(statement=>Q1)
。现在,当我们尝试执行T1
时,我们将看到状态2
,包括之前语句的所有更改,因此包括来自Q2
的值DateTime.Now.ToString("dd.MM.yyyy - HH\\:mm")
。这不是我们想要的。
解决方法可能是为每个INSERT添加一个唯一的标识符(例如,从一个单独的SEQUENCE对象),然后使用MAX。
对不起。分布式交易很困难:)