😊

SnowflakeのSQL変数にはカーソルの行変数の値を直接代入できないが、Snowflakeスクリプト変数を経由すると代入できる。

2022/09/04に公開

Snowflakeを実装中に変数の種類によって代入方法等の違いがあり、初めて利用した際に混乱してしまったのでここで整理しておこうと思う。


今回利用したSnowflakeの変数の種類

今回は自身がSnowflake で扱った下記の3種類の変数について整理を行う。

変数の種類(リンクはSnowflake公式ページ) 代入時の記述例 使用時の記載例 宣言 有効なスコープ
Snowfalkeスクリプト変数 work1 := 1; SELECT :work1; declare句内、またはbegin句内でLET BEGIN~END内 ≒ ローカル
SQL変数・セッション変数 SET (var2) = 1; SELECT $var2; 不要だが、Snowflakeスクリプト内で利用する際は、その前にSETしておく必要がある。 同一セッション中どこでも ≒ グローバル
行変数(カーソルをFORループで使用時の1行分) 不可(FOR文により自動) select row3.COL4; for文 for文内 ≒ ローカル

SnowflakeのSQL変数には行変数を直接代入するサンプルスクリプト

上手く実行できたスクリプトのサンプルは下記の通り
※下記はSnowflakeのワークシート上での実行を想定しています。

sucess_template.sql
--サンプル用テーブル TABLE_A
create or replace table TABLE_A as (
  select 5 COL4
);

-- SQL変数「val2」初期化。Snowflakeスクリプト内で使う前にSETしておく必要がある。
SET(val2) = 0; 

-- サンプルSnowflakeスクリプト
execute immediate $$
declare
  work1 STRING; -- Snowflakeスクリプト変数「work」定義
  crs cursor for select * from TABLE_A; -- カーソル定義
begin
  for row3 in crs do -- for文・行変数定義「row1」定義
    -- SET(val2) = row3.COL4; -- SQL変数へ <- 行変数 を代入は「Uncaught exception of type 'STATEMENT_ERROR' on line ...」の例外が発生して実行できない。
    work1 := row3.COL4; -- Snowflakeスクリプト変数へ <- 行変数 を代入
    SET(val2) = :work1; -- SQL変数へ <- Snowflakeスクリプト変数 を代入
  end for;
  return $val2;
end;
$$

まとめ

実現は可能だったが他のやり方があるのかもしれない。
ちなみに、SQL変数の更新は単独で実行したとしてもそこそこコストが高いかもしれない。
実行時間により課金される事を鑑みればほかの手段が取れるのであれば、積極的に選択しない方が良いのかもしれない。
※自分は避けれない事情があったので利用して居ますが。。。

Discussion