PostgreSQLスキルアップノート(自己啓発のための個人サイト)

SQL関数


【一覧に戻る】


━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
■■■■ PostgreSQL スキルアップノート
■■■■
■◆■■ SQL関数
■■■■
■■■■
■■■■ 2012/12/22
■■■■ 使用環境:PostgreSQL9.1.4 (CentOS6.2)
                                                                   (C) 2012 ohdb
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
★自己都合によりマニュアルへのリンクは9.2としています。ご了承下さい。
★このページはそのままカット&ペーストで実行して試すことができます。


【マニュアル】

問い合わせ言語(SQL)関数
→●[マニュアル]

CREATE FUNCTION 
→●[マニュアル]

【参考記事】




■■ SQL関数とは?
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SQL関数とはSQLによるユーザ定義関数。
正式名は「問い合わせ言語(SQL)関数」

機能は限られるが、シンプルで扱いやすく、用途によってはかなり利用価値があると思う。


【参考】ユーザ定義関数は、SQL関数以外も合わせて以下の4種類ある。

・問い合わせ言語(SQL)関数 ・・・SQLで作成された関数 
・手続型言語関数     ・・・PL/pgSQLやPL/Tclなどで作成された関数 
・内部関数        ・・・Cで作成されたPostgreSQLサーバに静的にリンクされた関数
・C言語関数        ・・・Cで作成された動的ロードされる関数

 本ページは「問い合わせ言語(SQL)関数」が対象。
 以下「SQL関数と呼ぶ。


【注意】関数とSQL関数

PostgreSQLからあらかじめ提供されている関数(例:sumなど)はあくまでも「関数」であって
「SQL関数」とは呼ばない。




■■ テスト用テーブル作成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

【□】 テーブル作成

drop table if exists t1; 
create table t1 (c1 serial primary key,c2 int,c3 text);
insert into t1 values
  (default,1000,'ABC'),
  (default,2000,'DEF'),
  (default,3000,'GHI'),
  (default,4000,'JKL'),
  (default,5000,'MNO');

select * from t1;


 c1 |  c2  | c3
----+------+-----
  1 | 1000 | ABC
  2 | 2000 | DEF
  3 | 3000 | GHI
  4 | 4000 | JKL
  5 | 5000 | MNO
(5 rows)






■1■ 引数なし・戻り値1個
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

引数なし・戻り値1個(または戻り値なし)のSQL関数の作り方。


基本

CREATE FUNCTION SQL関数名() RETURNS 戻り値の型 AS $$
   SELECT 文など;
$$ LANGUAGE SQL;


(戻り値なしの場合はRETURNSに void と指定)


本項の書き方では、以下の条件あり

・関数の中に記述するSELECT文は1個のカラムを表示するように作成する必要がある。
  複数カラムのSELECTは不可。

・結果が複数行返るようなSELECT文でも問題ないが、
 最初に出力された1件だけが戻り値の対象になる

・SQL文を複数記述することは不可能ではないが最後に実行したSQLの
  結果が戻り値になる。
 (SELECTやRETURNING句を持つINSERT,UPDATE,DELETE)

・戻り値の型は例のようにデータ型を指定する他、
  returns t1.c3%TYPE のようにテーブルの型を参照することも可能。


【□】例1 基本

drop function fnc_test11();
create or replace function fnc_test11() returns int AS $$
    SELECT min(c2)  from t1;
$$ LANGUAGE SQL;
select fnc_test11();

 
 fnc_test11
-----------
      1000




【□】例2 複数の文は最後の文の結果が返る

drop function fnc_test12();
create or replace function fnc_test12() returns intr AS $$
    SELECT max(c2)  from t1;   -- こちらは戻り値にはならない
    SELECT min(c2)  from t1;   -- こちらが戻り値の対象
$$ LANGUAGE SQL;
select fnc_test12();


 fnc_test12
-----------
      1000



【□】例3 複数行は最初の行が返る

drop function fnc_test13();
create or replace function fnc_test13() returns varchar AS $$
    SELECT c3 from t1 order by c1;
$$ LANGUAGE SQL;
select fnc_test13();


 fnc_test13
-----------
 ABC

 ・・ SELECT c3 from t1 order by c1の結果は5行あるが最初の1件が返る。


【□】例4 何も結果を返さない(void)

drop function fnc_test14();
create or replace function fnc_test14() returns void AS $$
    UPDATE t1 set c3='aaaaaaa' where c1=1;
$$ LANGUAGE SQL;
select fnc_test14();


 fnc_test14
-----------
 


■2■ 複数行の戻り値
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


1.SETOFを使う方法
──────────────────────────────

複数行を返すようにするにはreturnsにsetofを追加。

【□】 SQL関数を作成

drop function fnc_test21();
create or replace function fnc_test21() returns setof varchar AS $$
    SELECT c3 from t1 order by c1;
$$ LANGUAGE SQL;
select fnc_test21();


 fnc_test21
------------
 ABC
 DEF
 GHI
 JKL
 MNO
(5 rows)


上記は単一の列を複数行戻しているが
戻り値の内容に応じて

SETOF RECORD
SETOF TABLE名
なども可


2.TABLEを使う方法
──────────────────────────────

returnsにsetof(またはsetof records)ではなくTABLEを使う方法。
(ここでのTABLEの意味に注意)

複数の列を戻せるのでOUTパラメータも使わなくても済む。
TABLEで戻す場合は、OUTやINOUTパラメータは使用不可。

標準SQLで規定されており、SETOFよりも移植面ではよい。(?)


【□】 SQL関数を作成

drop function fnc_test22();
create or replace function fnc_test22() returns table(col1 integer,col3 text) AS $$
    SELECT c1,c3 from t1 order by c1;
$$ LANGUAGE SQL;
select * from fnc_test22();


 col1 | col3
------+------
    1 | ABC
    2 | DEF
    3 | GHI
    4 | JKL
    5 | MNO




■3■ in引数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


基本

CREATE FUNCTION SQL関数名(引数1の型,引数2の型・・) RETURNS 戻り値の型 AS $$
    SELECT 文など;
$$ LANGUAGE SQL;


・関数の中では$1,$2のように番号で値を利用。
(ただし9.2以降は引数に名前を付けられる)

・9.2より引数に名前をつけることが可能

今回省略(詳細はマニュアル参照)
例)CREATE FUNCTION fnc_test(x integer, y integer) RETURNS integer AS $$
      SELECT kingaku from table WHERE c1=x and c2=y;
    $$ LANGUAGE SQL;



【□】 SQL関数を作成

drop function if exists fnc_test31(int);
create or replace function fnc_test31(int) returns setof int AS $$
    SELECT c2 from t1 where c2 >= $1 order by c2;
$$ LANGUAGE SQL;




 select fnc_test31(2000);

 fnc_test32
------------
       2000
       3000
       4000
       5000


参照は以下のようにテーブルと同じように扱うこともできる。
マニュアルの「テーブルソースとしてのSQL関数」の節を参照


 select * from fnc_test32(2000);

 fnc_test32
------------
       2000
       3000
       4000
       5000


select * from t1 join fnc_test32(2000) c2list on t1.c2=c2list;

select * from t1,fnc_test32(2000) c2list where t1.c2=c2list;

 c1 |  c2  | c3  | c2list
----+------+-----+--------
  2 | 2000 | DEF |   2000
  3 | 3000 | GHI |   3000
  4 | 4000 | JKL |   4000
  5 | 5000 | MNO |   5000



■4■ out引数
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


【□】 SQL関数を作成

drop function fnc_test41(in int,in varchar,out int,out int,out varchar);
CREATE FUNCTION fnc_test41(in int,in varchar,out int,out int,out varchar) returns setof record AS $$
    SELECT c1,c2,c3 from t1 where c2=$1 or c3=$2;
$$ LANGUAGE SQL;



SELECT fnc_test41(5000,'ABC') ;

  fnc_test41
--------------
 (1,1000,ABC)
 (5,5000,MNO)



参照は以下のようにテーブルと同じように扱うこともできる。
マニュアルの「テーブルソースとしてのSQL関数」の節を参照


SELECT * FROM fnc_test41(5000,'ABC');

 column1 | column2 | column3
---------+---------+---------
       1 |    1000 | ABC
       5 |    5000 | MNO


SELECT * FROM fnc_test41(5000,'ABC') a where  a.column3='ABC';

 column1 | column2 | column3
---------+---------+---------
       1 |    1000 | ABC



■5■ 戻り値の型としてテーブルを指定する方法
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

【□】 SQL関数を作成

CREATE FUNCTION fnc_test51(int) RETURNS SETOF t1 AS $$
    SELECT * FROM t1 WHERE c2 > $1;
$$ LANGUAGE SQL;


SELECT * FROM fnc_test51(3000);

 c1 |  c2  | c3
----+------+-----
  4 | 4000 | JKL
  5 | 5000 | MNO



【参考】なぜSETOFの次にテーブル名がくるのか? 

    SETOF t1

    ・・・これはテーブル名ではなくテーブル名t1と同名の複合型のデータ型である。
          CREATE TABLEする際に、テーブル名と同じ名前のデータ型も自動的に作成される。

          ・CREATE TABLE→●[マニュアル]
            「さらにCREATE TABLEは、作成するテーブルの1行に対応する複合型のデータ型を作成します。」





■6■引数のデフォルト値
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

略

詳細はマニュアル「引数にデフォルト値を持つSQL関数」の節を参照




■7■ SQL関数の確認
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━


【□】 \df fnc_test*
                           List of functions
 Schema |    Name    | Result data type  | Argument data types |  Type
--------+------------+-------------------+---------------------+--------
 public | fnc_test11 | integer           |                     | normal
 public | fnc_test12 | integer           |                     | normal
 public | fnc_test13 | character varying |                     | normal
 public | fnc_test14 | void              |                     | normal

【□】 \df fnc_test2*

                                                       List of functions
 Schema |    Name    | Result data type |                             Argument data types                             |  Type
--------+------------+------------------+-----------------------------------------------------------------------------+-------- public | fnc_test21 | record           | integer, character varying, OUT integer, OUT integer, OUT character varying | normal
 public | fnc_test22 | integer          |                                                                             | normal




ソースコードも表示するには+を付ける。

【□】 \df+ fnc_test21


                              List of functions

 Schema |    Name    |・・ |         Source code          | Description
--------+------------+・・-+------------------------------+-------------
 public | fnc_test11 |・・ |                             +|
        |            |・・ |     SELECT min(c2)  from t1;+|
        |            |・・ |                              |


以上 
inserted by FC2 system