获取在Snowflake Datawarehouse中插入的行的标识

时间:2018-12-18 17:08:12

标签: sql snowflake-datawarehouse

如果我有一个带有自动递增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

1 个答案:

答案 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语句,因此可能发生以下情况

  • 两个查询Q2Q1进行一个简单的单行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。

对不起。分布式交易很困难:)