次の 2 つの PostgreSQL 関数について考えてみましょう。
CREATE OR REPLACE FUNCTION f_1 (v1 INTEGER, v2 OUT INTEGER)
AS $$
BEGIN
v2 := v1;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION f_2 (v1 INTEGER)
RETURNS TABLE(v2 INTEGER)
AS $$
BEGIN
v2 := v1;
END
$$ LANGUAGE plpgsql;
「通常の」手続き型 SQL 言語 (Transact-SQL など) では、2 つのタイプの関数はまったく異なります。f_1
実際にはプロシージャになりf_2
ますが、テーブル値関数になります。SQL Server では、後者は次のINFORMATION_SCHEMA.ROUTINES
ように返されます。
SELECT r.routine_schema, r.routine_name
FROM information_schema.routines r
WHERE r.routine_type = 'FUNCTION'
AND r.data_type = 'TABLE'
ただし、PostgreSQL ではこれは機能しません。f_1
次のクエリは、とのシグネチャに本質的な違いがないことを示していますf_2
。
SELECT r.routine_name, r.data_type, p.parameter_name, p.data_type
FROM information_schema.routines r
JOIN information_schema.parameters p
USING (specific_catalog, specific_schema, specific_name);
上記の結果は次のとおりです。
routine_name | data_type | parameter_name | data_type
-------------+-----------+----------------+----------
f_1 | integer | v1 | integer
f_1 | integer | v2 | integer
f_2 | integer | v1 | integer
f_2 | integer | v2 | integer
関数から複数の列が返された場合、事態はそれほど良くなりません。その場合、「正式な」戻り値の型さえありません。ただrecord
:
CREATE OR REPLACE FUNCTION f_3 (v1 INTEGER, v2 OUT INTEGER, v3 OUT INTEGER)
AS $$
BEGIN
v2 := v1;
END
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION f_4 (v1 INTEGER)
RETURNS TABLE(v2 INTEGER, v3 INTEGER)
AS $$
BEGIN
v2 := v1;
END
$$ LANGUAGE plpgsql;
...私は得るでしょう:
routine_name | data_type | parameter_name | data_type
-------------+-----------+----------------+----------
f_3 | record | v1 | integer
f_3 | record | v2 | integer
f_3 | record | v3 | integer
f_4 | record | v1 | integer
f_4 | record | v2 | integer
f_4 | record | v3 | integer
他のデータベースからのものである場合、字句署名の意図は明らかにまったく異なります。オラクルの人として、副作用があることを期待PROCEDURES
していますFUNCTIONS
が、(自律型トランザクションでない限り) 副作用はなく、SQL に安全に埋め込むことができます。OUT
PostgreSQL がすべての関数をテーブルとして巧みに扱うことは知っていますが、どのクエリでもパラメータをテーブル列として設計するのは良い考えではないと思います...
私の質問は:
関数を宣言する 2 つの方法に形式上の違いはありますか? ある場合、INFORMATION_SCHEMA
または からどのように発見できPG_CATALOG
ますか?