1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Snowflakeのアンロードの結果が0件だった時をハンドリングしたい

Last updated at Posted at 2024-10-06

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で実行した場合、画面上に以下のような実行結果が表示されます。

image.png

この実行結果のうち、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件の時に実行すると、下記のように例外が発生します。

image.png

これで、アンロードの結果が0件だった時をハンドリングすることができました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?