Snowflakeのアンロード(COPY INTO <location>
)は、テーブルの内容をS3などのロケーションにファイルとして出力します。この処理は、テーブルの件数が0件だった時はアンロード処理を行わないとドキュメントに書かれています。
If the source table contains 0 rows, then the COPY operation does not unload a data file.
しかし0件の時に何らかの処理(例:空ファイルを作成する、例外を発生させる)を行いたい場合があります。そのためには、COPY INTO <location>
処理の実行結果を利用します
COPY INTO <location>の結果を確認する
例えば、データが存在するmytable
テーブルのデータを、my_ext_unload_stage
外部ステージにアンロードする処理を実行してみます。
COPY INTO @my_ext_unload_stage/d1 from mytable
このSQLをSnowflakeのUIで実行した場合、画面上に以下のような実行結果が表示されます。
この実行結果のうち、rows_unloaded
が実際にアンロードされた件数となります。この実行結果をプログラム的に取得することができれば、0件だった時の処理を書くことができます。
COPY INTO <location>の結果をカーソルで取得する
COPY INTO <location>
処理の実行結果は、括弧で囲むことでカーソルとして得ることができます。先ほどの実行結果で分かるように、rows_unloaded
は一列目にあるので、FETCH
で指定する最初の変数に値が設定されます。なお、変数やIF文などを利用するため、ストアードプロシージャーとして実行する必要があります。ここでは匿名プロシージャーを使って0件だった時に例外を発生させるようにします。
WITH unload_sample_proc AS PROCEDURE()
RETURNS VARCHAR
LANGUAGE SQL
AS
$$
DECLARE
rs RESULTSET;
rows_unloaded INTEGER DEFAULT 0;
UNLOAD_EXCEPTION EXCEPTION;
BEGIN
-- アンロード処理を行い、結果をrs変数に保存する
rs := (COPY INTO @my_ext_unload_stage/d1 FROM mytable);
LET cur CURSOR FOR rs;
OPEN cur;
FETCH cur INTO rows_unloaded;
IF (rows_unloaded = 0) THEN
-- アンロード件数が0件だった時の処理
RAISE UNLOAD_EXCEPTION;
END IF;
CLOSE cur;
END;
$$
CALL unload_sample_proc()
;
このプログラムをmytable
テーブルが0件の時に実行すると、下記のように例外が発生します。
これで、アンロードの結果が0件だった時をハンドリングすることができました。