Получить идентификатор строки, вставленной в Snowflake Datawarehouse - PullRequest
0 голосов
/ 18 декабря 2018

Если у меня есть таблица с автоматически возрастающим столбцом идентификатора, я бы хотел иметь возможность вставить строку в эту таблицу и получить идентификатор только что созданной строки.Я знаю, что, как правило, вопросы StackOverflow нуждаются в некотором коде, который был предпринят, или в исследовательской работе, но я не уверен, с чего начать со Snowflake.Я просмотрел их документацию и ничего для этого не нашел.

Лучшее, что я мог сделать на данный момент, это попробовать result_scan() и last_query_id(), но они не дают мне никакой соответствующей информации о добавленной строке, только подтверждение того, что строка была вставлена.

Я считаю, что то, о чем я прошу, соответствует функции SCOPE_IDENTITY() MS SQL Server.

Существует ли функция, эквивалентная Снежинке, для MS SQL Server SCOPE_IDENTITY()?

РЕДАКТИРОВАТЬ: ради наличия здесь кода:

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 голосов
/ 23 декабря 2018

ПРИМЕЧАНИЕ: ответ ниже может быть не на 100% правильным в некоторых очень редких случаях, см. Ниже раздел ОБНОВЛЕНИЕ

Оригинальный ответ

Снежинка не даетэквивалент SCOPE_IDENTITY сегодня.

Однако вы можете использовать путешествие во времени Снежинки для получения максимального значения столбца сразу после выполнения данного оператора.

Вот пример:

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 вручную, это может повлиять на результат этого запроса.

ОБНОВЛЕНИЕ

Обратите внимание, я понял, что приведенный выше код может редко генерировать неправильный ответ.

Поскольку порядок выполнения различных фаз запроса в распределенной системе, такой как Snowflake, может быть недетерминированным, а Snowflake допускает одновременные операторы INSERT, может произойти следующее

  • Два запроса Q1 и Q2, сделать простую однорядную INSERT, начать примерно в то же время
  • Q1 запускается, немного впереди
  • Q2 запускается
  • Q1 создает строку со значением1 из столбца IDENTITY
  • Q2 создает строку со значением 2 из столбца IDENTITY
  • Q2 опережает Q1 - этоключевая часть
  • Q2 фиксируется, помечается как завершенная в момент T2
  • Q1 фиксируется, помечается как завершенная в момент T1

Обратите внимание, что T1 позже T2.Теперь, когда мы попытаемся сделать SELECT ... AT(statement=>Q1), мы увидим состояние по состоянию на T1, включая все изменения по сравнению с предыдущими утверждениями, следовательно, включая значение 2 с Q2.Это не то, что нам нужно.

Обходной путь может заключаться в добавлении уникального идентификатора к каждой INSERT (например, из отдельного объекта SEQUENCE), а затем использования MAX.

Извините.Распределенные транзакции сложны:)

...