DML コマンドの影響を受ける行数の決定

DML コマンド が実行された後( TRUNCATE TABLE コマンドを除く)、Snowflake Scripting は以下のグローバル変数をセットします。これらの変数を使用して、最後の DML ステートメントが行に影響を与えたかどうかを判別できます。

変数

説明

SQLROWCOUNT

最後の DML ステートメントの影響を受けた行の数。

これは、 JavaScript ストアドプロシージャの getNumRowsAffected() と同等です。

SQLFOUND

最後の DML ステートメントが1つ以上の行に影響を与えた場合は true

SQLNOTFOUND

最後の DML ステートメントがゼロ行に影響を与えた場合は true

注釈

2025_01動作変更バンドル は、これらの変数の動作を変更します。バンドルが有効な場合、Snowflake Scriptingブロックまたはストアドプロシージャの最後の DML ステートメントの後に DML 以外のステートメントが実行されると、変数は NULL を返します。バンドルはデフォルトで有効になっています。動作変更の詳細情報については、 Snowflake Scripting: グローバル変数に対する変更点 をご覧ください。

バンドルが無効になっている場合は、以下のステートメントを実行することで、 アカウントで有効にする ことができます。

SELECT SYSTEM$ENABLE_BEHAVIOR_CHANGE_BUNDLE('2025_01');
Copy

バンドルを無効にするには、以下のステートメントを実行します。

SELECT SYSTEM$DISABLE_BEHAVIOR_CHANGE_BUNDLE('2025_01');
Copy

このセクションの例では、次のテーブルを使用します。

CREATE OR REPLACE TABLE my_values (value NUMBER);
Copy

次の例では、 SQLROWCOUNT 変数を使用して、最後の DML ステートメント(INSERT ステートメント)の影響を受けた行数を返します。

BEGIN
  LET sql_row_count_var INT := 0;
  INSERT INTO my_values VALUES (1), (2), (3);
  sql_row_count_var := SQLROWCOUNT;
  SELECT * from my_values;
  RETURN sql_row_count_var;
END;
Copy

注意: Snowflake CLISnowSQLClassic Consoleexecute_streamexecute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。

EXECUTE IMMEDIATE $$
BEGIN
  LET sql_row_count_var INT := 0;
  INSERT INTO my_values VALUES (1), (2), (3);
  sql_row_count_var := SQLROWCOUNT;
  SELECT * from my_values;
  RETURN sql_row_count_var;
END;
$$;
Copy
+-----------------+
| anonymous block |
|-----------------|
|               3 |
+-----------------+

次の例では、 SQLFOUND 変数と SQLNOTFOUND 変数を使用して、最後の DML ステートメント(UPDATE ステートメント)の影響を受ける行数を返します。

BEGIN
  LET sql_row_count_var INT := 0;
  LET sql_found_var BOOLEAN := NULL;
  LET sql_notfound_var BOOLEAN := NULL;
  IF ((SELECT MAX(value) FROM my_values) > 2) THEN
    UPDATE my_values SET value = 4 WHERE value < 3;
    sql_row_count_var := SQLROWCOUNT;
    sql_found_var := SQLFOUND;
    sql_notfound_var := SQLNOTFOUND;
  END IF;
  SELECT * from my_values;
  IF (sql_found_var = true) THEN
    RETURN 'Updated ' || sql_row_count_var || ' rows.';
  ELSEIF (sql_notfound_var = true) THEN
    RETURN 'No rows updated.';
  ELSE
    RETURN 'No DML statements executed.';
  END IF;
END;
Copy

注意: Snowflake CLISnowSQLClassic Consoleexecute_streamexecute_string メソッドを Python Connector コードで使用する場合は、代わりにこの例を使用してください(Snowflake CLI、 SnowSQL、 Classic Console、Python ConnectorでSnowflake Scriptingを使用する を参照)。

EXECUTE IMMEDIATE $$
BEGIN
  LET sql_row_count_var INT := 0;
  LET sql_found_var BOOLEAN := NULL;
  LET sql_notfound_var BOOLEAN := NULL;
  IF ((SELECT MAX(value) FROM my_values) > 2) THEN
    UPDATE my_values SET value = 4 WHERE value < 3;
    sql_row_count_var := SQLROWCOUNT;
    sql_found_var := SQLFOUND;
    sql_notfound_var := SQLNOTFOUND;
  END IF;
  SELECT * from my_values;
  IF (sql_found_var = true) THEN
    RETURN 'Updated ' || sql_row_count_var || ' rows.';
  ELSEIF (sql_notfound_var = true) THEN
    RETURN 'No rows updated.';
  ELSE
    RETURN 'No DML statements executed.';
  END IF;
END;
$$;
Copy

匿名ブロックが実行されると、 UPDATE ステートメントが2行を更新するため、 SQLFOUND 変数は true になります。

+-----------------+
| anonymous block |
|-----------------|
| Updated 2 rows. |
+-----------------+

現在の値を確認するためにテーブルをクエリします。

SELECT * FROM my_values;
Copy
+-------+
| VALUE |
|-------|
|     4 |
|     4 |
|     3 |
+-------+

同じ匿名ブロックをもう一度実行すると、結果は次のようになります。

  • 2 よりも大きい値がテーブル内にあるため、 UPDATE ステートメントが実行されます。つまり、 IF の条件は満たされています。

  • 行が更新されていないため、変数 SQLNOTFOUNDtrue です。テーブル内のどの値も 3 (WHERE 句で指定)より小さいため、 UPDATE ステートメントは行を更新しません。

クエリは次の出力を返します。

+------------------+
| anonymous block  |
|------------------|
| No rows updated. |
+------------------+

次に、テーブルを更新し、すべての値を 1 にセットします:

UPDATE my_values SET value = 1;

SELECT * FROM my_values;
Copy
+-------+
| VALUE |
|-------|
|     1 |
|     1 |
|     1 |
+-------+

同じ匿名ブロックを再度実行すると、 UPDATE ステートメントは実行されません。なぜなら、テーブル内のどの値も 2 よりも大きくないからです。つまり、 IF の条件が満たされていないので、 UPDATE ステートメントは実行されません。

+-----------------------------+
| anonymous block             |
|-----------------------------|
| No DML statements executed. |
+-----------------------------+