Tips

IF文でEXECUTE IMMEDIATEは使えない?!?!

 BigQueryでやりたかったこと

日別で作成されるテーブルのレコード数を確認し、レコード数が0行の場合は後続のスクリプトを実行しないようにしたい。

 

ダメだったクエリ

--実行日の日付を取得し、getDate()にYYYYMMDDの形で格納
CREATE TEMPORARY FUNCTION getDate() AS (FORMAT_DATE("%Y%m%d", CURRENT_DATE("Asia/Tokyo")));

--table_YYYYMMDDテーブルのレコード数が0の場合はスクリプトの実行を止める
IF EXECUTE IMMEDIATE FORMAT(""(SELECT COUNT(*) FROM `table_%s`)"", getDate()) = 0 THEN
    RETURN;
END IF;

このクエリを実行すると、以下のエラーが発生しました。
Syntax error: Function call cannot be applied to this expression.

どこの構文がどう違うのか全然わからないので、発狂したくなりました笑
あーでもないこーでもないと試行錯誤し、見つけたのが次の情報です。
公式のEXECUTE IMMEDIATEの項目

IF のような制御ステートメントは使用できません。

と書いてあり、絶望しました笑

先輩に相談すると素敵なヒントをいただけたので、サクッと解決できました。羨望の眼差しです。

結論

【先ほどまでの考え】
・IF文の中でFORMAT関数を用いて、指定した値を返す
(※1度にすべての処理を行おうとしていた)

【新たな考え】
1.先に作成したい文字列を一時テーブルとして仮置き
2.作成した一時テーブルを用いてIF文を作成

 

成功したクエリ

DECLARE table_name STRING;

--実行日の日付を取得し、getDate()にYYYYMMDDの形で格納
CREATE TEMPORARY FUNCTION getDate() AS (FORMAT_DATE("%Y%m%d", CURRENT_DATE("Asia/Tokyo")));

--1.一時テーブルの仮置き
SET table_name = CONCAT('`table_', getDate(), '`');
EXECUTE IMMEDIATE CONCAT('CREATE OR REPLACE TEMP TABLE temporary AS SELECT * FROM ', table_name);

--2.作成した一時テーブル(temporary)を使ってIF文を作成
IF (SELECT COUNT(*) FROM temporary) = 0 THEN
    RETURN;
END IF;

 

おわりに

皆さんが完全に同じクエリを書くことはないと思いますが、いつかの誰かが困ったときのヒント記事になれば嬉しいです。私が今回学んだのは1つの方法に固執しないこと。
頭を柔らかくして、違うアプローチが考えられるようになりたいものですね。

 

Madoka
Snow Manが好きな自由人。平日は頭を動かし、休日は身体を動かしてます。ダンスとバク転を特訓中。