【Snowflake】ストアド ~ クエリ結果を受け取る ~

■ はじめに

https://dk521123.hatenablog.com/entry/2022/12/23/223345

のサンプルで、
ストアド内で Countの結果を使って処理したが
詳細は、あんまりよく分からず作った。

そこで、今回は、クエリ結果を受け取り処理することを
深堀りしてみた。

目次

【0】クエリ結果を受け取るには
【1】結果セット / RESULTSET
【2】カーソル / Cursor
【3】テーブル関数
【4】サンプル
 例1:Table表示
 例2:Count 結果を表示

【0】クエリ結果を受け取るには

以下のような手順で処理できる

手順

1)クエリ結果を結果セット(RESULTSET)で受け取る
2)FORループなどでカーソルを開く(?)
3)カーソル を使用して RESULTSET を反復処理する
 => まずは、「結果セット」「カーソル」について、取り上げる


https://dk521123.hatenablog.com/entry/2022/12/23/223345

-- のサンプルより

-- 1)クエリ結果を結果セット(RESULTSET)で受け取る
-- <resultset_name> := ( <query> ) ;
let result_set resultset := (select count(*) as row_count from demo_users where id = :id);

-- 2)FORループなどでカーソルを開く(?)
let cursor_result_set cursor for result_set;

-- 2)&3)一行で記述できる
-- let cursor_result_set cursor for select count(*) as row_count from invoices where id = :id

-- 3)カーソル を使用して RESULTSET を反復処理する
for row_variable in cursor_for_result_set do
  let row_count number := row_variable.row_count;
  ...
end for;

【1】結果セット / RESULTSET

クエリ結果の SQL データ型
 => 実体としては、クエリ結果へのポインタ

let res resultset default (select price from invoices);

【2】カーソル / Cursor

https://docs.snowflake.com/ja/developer-guide/snowflake-scripting/cursors.html

結果セットを 1 レコードずつループして処理するための仕組み
 => (SQLのカーソルだが)カーソルに関しての詳細は、
  以下の関連記事を参照のこと。

https://dk521123.hatenablog.com/entry/2012/01/02/014343

【3】テーブル関数

https://docs.snowflake.com/ja/sql-reference/functions-table.html

より抜粋
~~~~~~~~~~~~~~
テーブル関数は、入力行ごとに行のセットを返します。
返されるセットには、0行、1行、またはそれ以上の行を含めることができます。
各行には、1つ以上の列を含めることができます。

テーブル関数は、「表形式関数」と呼ばれることがあります。
~~~~~~~~~~~~~~


https://docs.snowflake.com/ja/sql-reference/functions-table.html#using-a-table-as-input-to-a-table-function

-- より抜粋

create or replace table dates_of_interest (event_date date);
insert into dates_of_interest (event_date) values
    ('2021-06-21'::date),
    ('2022-06-21'::date);

create or replace function record_high_temperatures_for_date(d date)
    -- table関数でReturnしている
    returns table (
       event_date date, city varchar, temperature number
    )
    as
    $$
    select d, 'New York', 65.0
    union all
    select d, 'Los Angeles', 69.0
    $$;

【4】サンプル

例1:Table表示

execute immediate $$
declare
  id varchar default 'x001';
  results resultset default (select * from demo_users where id = :id);
begin
  return table(results);
end;
$$
;

例2:Count 結果を表示

execute immediate $$
declare
  -- ★ここの値を変更して動作確認してください★
  id varchar default 'x001';
  result varchar default '-';
begin
  let result_set resultset := (select count(*) as row_count from demo_users where id = :id);
  let cursor_for_result_set cursor for result_set;
  for row_variable in cursor_for_result_set do
    let row_count number := row_variable.row_count;
    if (row_count <= 0) then
      result := 'Non-Value';
    else
      result := 'Result = ' || row_count::varchar;
    end if;
  end for;
  return result;
end;
$$
;

関連記事

Snowflake ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2021/11/02/130111
Snowflake ~ 入門編 / Hello world
https://dk521123.hatenablog.com/entry/2021/11/22/212520
Snowflake】ストアド ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2022/12/11/202904
Snowflake】ストアド ~ 基本編 / 条件分岐 ~
https://dk521123.hatenablog.com/entry/2022/12/26/211349
Snowflake】ストアド ~ 基本編 / ループ ~
https://dk521123.hatenablog.com/entry/2022/12/16/143349
Snowflake】ストアド ~ EXECUTE IMMEDIATE ~
https://dk521123.hatenablog.com/entry/2022/12/17/000217
Snowflake】ストアド ~ 例外 / EXCEPTION ~
https://dk521123.hatenablog.com/entry/2022/12/23/223345
Snowflake】ストアド ~ デバッグログについて ~
https://dk521123.hatenablog.com/entry/2022/12/18/121334
ストアド ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2010/08/06/112528
SQL Server】ストアド ~ 基本編 / カーソル ~
https://dk521123.hatenablog.com/entry/2012/01/02/014343