バージョンごとのドキュメント一覧

43.12. PL/pgSQLによる開発向けのヒント #

<title>Tips for Developing in <application>PL/pgSQL</application></title>

One good way to develop in <application>PL/pgSQL</application> is to use the text editor of your choice to create your functions, and in another window, use <application>psql</application> to load and test those functions. If you are doing it this way, it is a good idea to write the function using <command>CREATE OR REPLACE FUNCTION</command>. That way you can just reload the file to update the function definition. For example: PL/pgSQLで開発する1つの良い方法は、関数を作成するのに自分の好きなテキストエディタを使い、もう1つのウィンドウでpsqlを使用して関数を読み込ませて試験を行うことです。 この方法で行う場合にはCREATE OR REPLACE FUNCTIONを使用して関数を作成する方が良いでしょう。 この方法でファイルを再読み込みすると、関数定義を更新することができます。 例えば以下のようにします。

CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $$
          ....
$$ LANGUAGE plpgsql;

While running <application>psql</application>, you can load or reload such a function definition file with: psqlを実行し、以下のように関数定義ファイルを読み込み、または再読み込みすることができます。

\i filename.sql

and then immediately issue SQL commands to test the function. その後すぐに、関数を試験するためにSQLコマンドを発行することができます。

Another good way to develop in <application>PL/pgSQL</application> is with a GUI database access tool that facilitates development in a procedural language. One example of such a tool is <application>pgAdmin</application>, although others exist. These tools often provide convenient features such as escaping single quotes and making it easier to recreate and debug functions. PL/pgSQLにおける開発のもう1つの良い方法は、手続き言語の開発機能を持つGUIデータベースアクセスツールを使用することです。 他にもありますが、pgAdminがこうしたツールの一例です。 こうしたツールは、単一引用符をエスケープさせたり、関数の作り直しやデバッグが容易に行えたりする便利な機能をよく持っています。

43.12.1. 引用符の扱い #

<title>Handling of Quotation Marks</title>

The code of a <application>PL/pgSQL</application> function is specified in <command>CREATE FUNCTION</command> as a string literal. If you write the string literal in the ordinary way with surrounding single quotes, then any single quotes inside the function body must be doubled; likewise any backslashes must be doubled (assuming escape string syntax is used). Doubling quotes is at best tedious, and in more complicated cases the code can become downright incomprehensible, because you can easily find yourself needing half a dozen or more adjacent quote marks. It's recommended that you instead write the function body as a <quote>dollar-quoted</quote> string literal (see <xref linkend="sql-syntax-dollar-quoting"/>). In the dollar-quoting approach, you never double any quote marks, but instead take care to choose a different dollar-quoting delimiter for each level of nesting you need. For example, you might write the <command>CREATE FUNCTION</command> command as: PL/pgSQL関数のコードはCREATE FUNCTION内で文字列リテラルとして指定されます。 単一引用符で囲む通常のやり方で文字列リテラルを記述する時、関数本体内部の全ての単一引用符を二重化しなければなりません。 同様に、全てのバックスラッシュを二重化しなければなりません。 なお、文字列としてエスケープする構文が使用されると仮定します。 引用符を単に重ねるやり方は最も冗長であり、簡単に想像できると思いますが、複雑な状態では数個以上の隣接した引用符が必要となるため、コードを率直には理解しにくくなります。 それに代わって推奨されるのは、関数本体をドル引用符の文字列リテラルとして記述することです(4.1.2.4を見てください)。 ドル引用符を用いるやり方では他の引用符を二重化する必要はありませんが、それぞれの入れ子になった階層ごとに異なったドル引用符による区切り符号を用いなければなりません。 例えば、CREATE FUNCTIONコマンドを以下のように記述しても構いません。

CREATE OR REPLACE FUNCTION testfunc(integer) RETURNS integer AS $PROC$
          ....
$PROC$ LANGUAGE plpgsql;

Within this, you might use quote marks for simple literal strings in SQL commands and <literal>$$</literal> to delimit fragments of SQL commands that you are assembling as strings. If you need to quote text that includes <literal>$$</literal>, you could use <literal>$Q$</literal>, and so on. このやり方では、SQLコマンドの中で単純なリテラル文字列に対して引用符を使用でき、文字列として集積したSQLコマンドの断片を区切るために$$を使用できます。 もし$$を含んだテキストを引用符で囲む時は、$Q$のような記述を使用できます。

The following chart shows what you have to do when writing quote marks without dollar quoting. It might be useful when translating pre-dollar quoting code into something more comprehensible. 以下の表はドル引用符を用いない時の引用符の記述法を示したものです。 ドル引用符を用いる以前における引用符の記述を理解するのに、この表は役立つと思われます。

1つの引用符 #

To begin and end the function body, for example: 関数本体の先頭と末尾。 以下に例を示します。

CREATE FUNCTION foo() RETURNS integer AS '
          ....
' LANGUAGE plpgsql;

Anywhere within a single-quoted function body, quote marks <emphasis>must</emphasis> appear in pairs. 関数本体内部では引用符は必ずペアで現れます。

2つの引用符 #

For string literals inside the function body, for example: 関数本体内部の文字列リテラル用。 以下に例を示します。

a_output := ''Blah'';
SELECT * FROM users WHERE f_name=''foobar'';

In the dollar-quoting approach, you'd just write: ドル引用符を用いる時は、次のように記述します。

a_output := 'Blah';
SELECT * FROM users WHERE f_name='foobar';

which is exactly what the <application>PL/pgSQL</application> parser would see in either case. どちらもPL/pgSQLパーサから見ると同一となります。

4つの引用符 #

When you need a single quotation mark in a string constant inside the function body, for example: 関数本体内部の文字列リテラル内の単一引用符がある場合。 以下に例を示します。

a_output := a_output || '' AND name LIKE ''''foobar'''' AND xyz''

The value actually appended to <literal>a_output</literal> would be: <literal> AND name LIKE 'foobar' AND xyz</literal>. 実際にa_outputに追加される値は、 AND name LIKE 'foobar' AND xyzです。

In the dollar-quoting approach, you'd write: ドル引用符を用いる時は、次のように記述します。

a_output := a_output || $$ AND name LIKE 'foobar' AND xyz$$

being careful that any dollar-quote delimiters around this are not just <literal>$$</literal>. なお、ドル引用符の区切り文字は$$だけとは限らないことに注意してください。

6つの引用符 #

When a single quotation mark in a string inside the function body is adjacent to the end of that string constant, for example: 関数本体内部の文字列内の単一引用符が、文字列定数の末尾にある場合。 以下に例を示します。

a_output := a_output || '' AND name LIKE ''''foobar''''''

The value appended to <literal>a_output</literal> would then be: <literal> AND name LIKE 'foobar'</literal>. 実際にa_outputに追加される値は、 AND name LIKE 'foobar'です。

In the dollar-quoting approach, this becomes: ドル引用符を用いる時は、次のようになります。

a_output := a_output || $$ AND name LIKE 'foobar'$$

10個の引用符 #

When you want two single quotation marks in a string constant (which accounts for 8 quotation marks) and this is adjacent to the end of that string constant (2 more). You will probably only need that if you are writing a function that generates other functions, as in <xref linkend="plpgsql-porting-ex2"/>. For example: 文字列定数内に 2つの単一引用符を持たせたい場合(これで8個の単一引用符になり)、かつ、この文字列定数の末尾にある場合(これで2個追加されます)。 おそらく、他の関数を生成する関数を作成する場合(例 43.10)のみにこれが必要になるでしょう。 以下に例を示します。

a_output := a_output || '' if v_'' ||
    referrer_keys.kind || '' like ''''''''''
    || referrer_keys.key_string || ''''''''''
    then return ''''''  || referrer_keys.referrer_type
    || ''''''; end if;'';

The value of <literal>a_output</literal> would then be: a_outputの値は以下のようになります。

if v_... like ''...'' then return ''...''; end if;

In the dollar-quoting approach, this becomes: ドル引用符を用いる時は、次のようになります。

a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$
    || referrer_keys.key_string || $$'
    then return '$$  || referrer_keys.referrer_type
    || $$'; end if;$$;

where we assume we only need to put single quote marks into <literal>a_output</literal>, because it will be re-quoted before use. ここで単一引用符は使用前に再評価されるため、a_output内部だけで必要であると仮定します。

43.12.2. コンパイル時と実行時の付加的チェック #

<title>Additional Compile-Time and Run-Time Checks</title>

To aid the user in finding instances of simple but common problems before they cause harm, <application>PL/pgSQL</application> provides additional <replaceable>checks</replaceable>. When enabled, depending on the configuration, they can be used to emit either a <literal>WARNING</literal> or an <literal>ERROR</literal> during the compilation of a function. A function which has received a <literal>WARNING</literal> can be executed without producing further messages, so you are advised to test in a separate development environment. 単純でありふれた問題が有害となる前の実例を発見するユーザを助けるためPL/PgSQLは付加的checksを提供します。 可能かどうかは設定に依存しますが、関数のコンパイルのときWARNINGまたはERRORを省略して使用できます。 WARNINGを指定された関数は、それ以上のメッセージを生成しないで実行できます。 したがって、分離された開発環境でテストを実行できます。

Setting <varname>plpgsql.extra_warnings</varname>, or <varname>plpgsql.extra_errors</varname>, as appropriate, to <literal>"all"</literal> is encouraged in development and/or testing environments. 開発環境やテスト環境では、plpgsql.extra_warningsplpgsql.extra_errorsを適切に"all"に設定することを勧めます。

These additional checks are enabled through the configuration variables <varname>plpgsql.extra_warnings</varname> for warnings and <varname>plpgsql.extra_errors</varname> for errors. Both can be set either to a comma-separated list of checks, <literal>"none"</literal> or <literal>"all"</literal>. The default is <literal>"none"</literal>. Currently the list of available checks includes: この付加的チェックでは、設定変数plpgsql.extra_warningsを警告のためにplpgsql.extra_errorsをエラーのために使用できます。 どちらも、カンマで区切ったチェックリストまたは"none"または"all"と設定できます。 デフォルトは"none"です。 現在指定できるチェックの一覧は以下の通りです。

shadowed_variables #

Checks if a declaration shadows a previously defined variable. 宣言が以前に定義した変数を隠すかどうかチェックする。

strict_multi_assignment #

Some <application>PL/pgSQL</application> commands allow assigning values to more than one variable at a time, such as <command>SELECT INTO</command>. Typically, the number of target variables and the number of source variables should match, though <application>PL/pgSQL</application> will use <literal>NULL</literal> for missing values and extra variables are ignored. Enabling this check will cause <application>PL/pgSQL</application> to throw a <literal>WARNING</literal> or <literal>ERROR</literal> whenever the number of target variables and the number of source variables are different. PL/pgSQLコマンドのいくつかは、SELECT INTOのように、一度に2つ以上の変数に値を割り当てることを許しています。 PL/pgSQLは、ない値に対してはNULLを使い、余分な変数は無視しますが、通常は対象の変数の数と元の変数の数は一致するべきです。 このチェックを有効にすると、PL/pgSQLは対象の変数の数と元の変数の数が異なる場合には必ずWARNINGまたはERRORを発生するようになります。

too_many_rows #

Enabling this check will cause <application>PL/pgSQL</application> to check if a given query returns more than one row when an <literal>INTO</literal> clause is used. As an <literal>INTO</literal> statement will only ever use one row, having a query return multiple rows is generally either inefficient and/or nondeterministic and therefore is likely an error. このチェックを有効にすると、PL/pgSQLINTO句が使われている場合、与えられた問い合わせが2行以上の行を返すかどうか確認します。 INTO文は必ず1行に対してのみ使われますので、複数の行を返す問い合わせがあるということは一般に非効率かつ/または非決定論的であり、そのためおそらくエラーです。

The following example shows the effect of <varname>plpgsql.extra_warnings</varname> set to <varname>shadowed_variables</varname>: 以下の例では、plpgsql.extra_warningsshadowed_variablesに設定した結果を示します。

SET plpgsql.extra_warnings TO 'shadowed_variables';

CREATE FUNCTION foo(f1 int) RETURNS int AS $$
DECLARE
f1 int;
BEGIN
RETURN f1;
END;
$$ LANGUAGE plpgsql;
WARNING:  variable "f1" shadows a previously defined variable
LINE 3: f1 int;
        ^
CREATE FUNCTION

The below example shows the effects of setting <varname>plpgsql.extra_warnings</varname> to <varname>strict_multi_assignment</varname>: 以下の例では、plpgsql.extra_warningsstrict_multi_assignmentに設定した結果を示します。

SET plpgsql.extra_warnings TO 'strict_multi_assignment';

CREATE OR REPLACE FUNCTION public.foo()
 RETURNS void
 LANGUAGE plpgsql
AS $$
DECLARE
  x int;
  y int;
BEGIN
  SELECT 1 INTO x, y;
  SELECT 1, 2 INTO x, y;
  SELECT 1, 2, 3 INTO x, y;
END;
$$;

SELECT foo();
WARNING:  number of source and target fields in assignment does not match
DETAIL:  strict_multi_assignment check of extra_warnings is active.
HINT:  Make sure the query returns the exact list of columns.
WARNING:  number of source and target fields in assignment does not match
DETAIL:  strict_multi_assignment check of extra_warnings is active.
HINT:  Make sure the query returns the exact list of columns.

 foo
-----

(1 row)