Oracle Table FUNCTIONの作成
おすすめ書籍
- 図解入門よくわかる最新Oracleデータベースの基本と仕組み[第4版] (How‐nual Visual Guide Book)
- Oracleの基本 ~データベース入門から設計/運用の初歩まで
- [改訂第4版]SQLポケットリファレンス
テーブル・ファンクションの作成と実行
「ファンクションの作成」では通常のファンクションを作成しましたが、
このページではSELECT文のFROM句にテーブル等の代わりに、ファンクションを用いて実行結果をテーブルとして扱う
テーブル・ファンクションについて記します。
ファンクションの結果をテーブルデータとして返す場合には、先ずはテーブルの1行のデータ型としてのレコード型を宣言します。
その後で、そのレコード型を使ってテーブル型というものを宣言します。
このテーブル・ファンクションでは、この宣言したレコード型・テーブル型を利用してテーブルのデータを返す様に振る舞わせます。
以下にレコード型、テーブル型の宣言の例を示します。
SQL> /* テスト・テーブルのレコード型の作成 */ SQL> CREATE OR REPLACE TYPE TypeTEST IS OBJECT (ID NUMBER, NAME VARCHAR2(32)); 2 / 型が作成されました。 SQL> /* テスト・テーブルのテーブル型の作成 */ SQL> CREATE OR REPLACE TYPE TableTypeTEST IS TABLE OF TypeTEST; 2 / 型が作成されました。
レコード型の宣言はテーブル作成の方法と同様に、カラム名とそのデータ型をリスト指定で行います。
テーブル型は使用するレコード型を指定します。
このレコード型・テーブル型を使用した簡単なテーブル・ファンクションの例を以下に示します。
SQL> /* 一括でテーブル内容を返す関数 */ SQL> CREATE OR REPLACE FUNCTION TABLE_FNC1 (NMAX NUMBER) 2 RETURN TableTypeTEST /* 戻り値:テーブル型 */ 3 IS 4 TableArr TableTypeTEST; /* ネストテーブル型宣言 */ 5 BEGIN 6 TableArr := TableTypeTEST(); /* ネストテーブル型初期化 */ 7 FOR I IN 1..NMAX LOOP 8 TableArr.EXTEND; /* テーブル拡張 */ 9 TableArr(I) := TypeTEST(I, 'TEST...' || TO_CHAR(I)); /* レコード設定 */ 10 END LOOP; 11 RETURN TableArr; /* ネストテーブルを返す */ 12 END; 13 / ファンクションが作成されました。
このファンクションの使い方は、 SELECT文のFROM句でTABLEと記述語テーブル・ファンクションを呼出す形で指定します。 実行例は以下の様になります。指定した3回までのレコードが生成されて返されるのが分かると思います。
SQL> SELECT * FROM TABLE(TABLE_FNC1(3)); ID NAME ---------- ---------------------------------------------------------------- 1 TEST...1 2 TEST...2 3 TEST...3
パイプライン・テーブル・ファンクションの作成と実行
上記のテーブル・ファンクションではデータ処理が終わるまではデータが返されませんが、 テーブル・ファンクションにパイプラインの属性を付加することで、 データが順次呼び出し元に返される様になります。 実行例は以下の様になります。指定した3回までのレコードが生成されて返されるのが分かると思います。
SQL> CREATE OR REPLACE FUNCTION TABLE_FNC1_PIPE (NMAX NUMBER) 2 RETURN TableTypeTEST PIPELINED /* 戻り値:テーブル型 */ 3 IS 4 BEGIN 5 FOR I IN 1..NMAX LOOP 6 PIPE ROW(TypeTEST(I, 'TEST_PIPE...' || TO_CHAR(I))); /* レコード設定 */ 7 END LOOP; 8 END; 9 / ファンクションが作成されました。 SQL> SELECT * FROM TABLE(TABLE_FNC1_PIPE(3)); ID NAME ---------- ---------------------------------------------------------------- 1 TEST_PIPE...1 2 TEST_PIPE...2 3 TEST_PIPE...3 SQL>
このファンクションで重要なのは PIPE ROW 文のところです。
PIPE ROW 文はファンクションの起動元に ( ) 内の行(表の要素)を戻します。
以下の例からも、ほぼ通常のテーブルの様に扱えます。
SQL> SELECT ID, '[' || NAME || ']' AS NAMEX FROM TABLE(TABLE_FNC1_PIPE(3)) 2 WHERE ID < 3 3 ORDER BY ID DESC; ID NAMEX ---------- -------------------------------------------------------------------- 2 [TEST_PIPE...2] 1 [TEST_PIPE...1]