In this section and the following ones, we describe all the statement types that are explicitly understood by <application>PL/pgSQL</application>. Anything not recognized as one of these statement types is presumed to be an SQL command and is sent to the main database engine to execute, as described in <xref linkend="plpgsql-statements-general-sql"/>. 本節および次節では、明示的にPL/pgSQLで解釈される、全ての種類の文について説明します。 これらの種類の文として認められないものはすべて、SQLコマンドであると仮定され、41.5.2において記述したように、メインデータベースエンジンに送信され実行されます。
An assignment of a value to a <application>PL/pgSQL</application> variable is written as: 値をPL/pgSQL変数に代入する場合は以下のように記述します。
variable
{ := | = }expression
;
As explained previously, the expression in such a statement is evaluated
by means of an SQL <command>SELECT</command> command sent to the main
database engine. The expression must yield a single value (possibly
a row value, if the variable is a row or record variable). The target
variable can be a simple variable (optionally qualified with a block
name), a field of a row or record target, or an element or slice of
an array target. Equal (<literal>=</literal>) can be
used instead of PL/SQL-compliant <literal>:=</literal>.
上述した通り、このような文中にある式は、メインデータベースエンジンに送信されるSELECT
SQLコマンドによって評価されます。
式は1つの値を生成しなければなりません
(変数が行変数またはレコード変数の場合は行値となるかもしれません)。
対象の変数は単純な変数(ブロック名で修飾可能)、行またはレコードの対象のフィールド、または配列の対象の要素またはスライスとすることができます。
等号(=
)がPL/SQLにおける代入記号(:=
)の代わりに使用できます。
If the expression's result data type doesn't match the variable's data type, the value will be coerced as though by an assignment cast (see <xref linkend="typeconv-query"/>). If no assignment cast is known for the pair of data types involved, the <application>PL/pgSQL</application> interpreter will attempt to convert the result value textually, that is by applying the result type's output function followed by the variable type's input function. Note that this could result in run-time errors generated by the input function, if the string form of the result value is not acceptable to the input function. 式の結果データ型が変数のデータ型に一致しない場合、値は代入キャスト(10.4を参照)と同様に変換されます。 関係する二つのデータ型のための代入キャストが無いときには、PL/pgSQLインタプリタは結果値を、変数のデータ型の入力関数に続けて結果データ型の出力関数を適用することで、テキストとして変換しようとします。 結果値の文字列形式が入力関数で受け付けることができない場合に、入力関数において実行時エラーが発生するかもしれないことに注意してください。
Examples: 例:
tax := subtotal * 0.06; my_record.user_id := 20; my_array[j] := 20; my_array[1:3] := array[1,2,3]; complex_array[n].realpart = 12.3;
In general, any SQL command that does not return rows can be executed within a <application>PL/pgSQL</application> function just by writing the command. For example, you could create and fill a table by writing 一般に、行を返さないSQLコマンドはPL/pgSQL関数内にそのコマンドを書くだけで実行されます。 例えば、テーブルを作成してデータを入れるには以下のように書けます。
CREATE TABLE mytable (id int primary key, data text); INSERT INTO mytable VALUES (1,'one'), (2,'two');
If the command does return rows (for example <command>SELECT</command>, or
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>/<command>MERGE</command>
with <literal>RETURNING</literal>), there are two ways to proceed.
When the command will return at most one row, or you only care about
the first row of output, write the command as usual but add
an <literal>INTO</literal> clause to capture the output, as described
in <xref linkend="plpgsql-statements-sql-onerow"/>.
To process all of the output rows, write the command as the data
source for a <command>FOR</command> loop, as described in
<xref linkend="plpgsql-records-iterating"/>.
《マッチ度[89.441931]》コマンドが行を返すのであれば(例えばSELECT
やRETURNING
を伴うINSERT
/UPDATE
/DELETE
など)、処理する方法が2つあります。
コマンドが多くても1行を返す場合、もしくは出力の最初の行だけに関心がある場合には、41.5.3に書かれているように、出力を取得するためのINTO
句を追加する以外は通常通りコマンドを書いてください。
出力行をすべて処理するためには、41.6.6に書かれているように、FOR
ループに対するデータソースとしてコマンドを書いてください。
《機械翻訳》コマンドが行を返す場合(例えばSELECT
、INSERT
/UPDATE
/DELETE
/MERGE
とRETURNING
を伴う)、2つの方法があります。
コマンドが最大1行を返す場合、または出力の最初の行だけを気にする場合は、通常どおりコマンドを書きますが、41.5.3で説明したように、INTO
句を追加して出力を取り込みます。
すべての出力行を処理するには、41.6.6で説明したように、FOR
ループのデータソースとしてコマンドを書いてください。
Usually it is not sufficient just to execute statically-defined SQL commands. Typically you'll want a command to use varying data values, or even to vary in more fundamental ways such as by using different table names at different times. Again, there are two ways to proceed depending on the situation. 通常、静的に定義されたSQLコマンドを実行するだけでは十分ではありません。 典型的には、可変のデータ値を使ったり、さらには異なる時には異なるテーブル名を使うなどより基本的な方法で変化したりするコマンドを使いたいでしょう。 今回も、状況に応じて2つの方法があります。
<application>PL/pgSQL</application> variable values can be
automatically inserted into optimizable SQL commands, which
are <command>SELECT</command>, <command>INSERT</command>,
<command>UPDATE</command>, <command>DELETE</command>,
<command>MERGE</command>, and certain
utility commands that incorporate one of these, such
as <command>EXPLAIN</command> and <command>CREATE TABLE ... AS
SELECT</command>. In these commands,
any <application>PL/pgSQL</application> variable name appearing
in the command text is replaced by a query parameter, and then the
current value of the variable is provided as the parameter value
at run time. This is exactly like the processing described earlier
for expressions; for details see <xref linkend="plpgsql-var-subst"/>.
PL/pgSQL変数値は、最適化可能なSQLコマンドに自動的に挿入できます。最適化可能なSQLコマンドとは、SELECT
、INSERT
、UPDATE
、DELETE
、MERGE
とEXPLAIN
やCREATE TABLE ... AS SELECT
のようなこのうちの1つを含む特定のユーティリティコマンドのことです。
このコマンドでは、コマンドテキストに現れるすべてのPL/pgSQL変数名は、問い合わせパラメータで置き換えられ、その後、実行時のパラメータ値として、その時点の変数値が提供されます。
これは以前に述べた式に関する処理と全く同じです。詳細は41.11.1を参照してください。
When executing an optimizable SQL command in this way, <application>PL/pgSQL</application> may cache and re-use the execution plan for the command, as discussed in <xref linkend="plpgsql-plan-caching"/>. 最適化可能なSQLコマンドがこのように実行されると、41.11.2に記述したように、PL/pgSQLはコマンドのために、実行計画をキャッシュして再利用します。
Non-optimizable SQL commands (also called utility commands) are not
capable of accepting query parameters. So automatic substitution
of <application>PL/pgSQL</application> variables does not work in such
commands. To include non-constant text in a utility command executed
from <application>PL/pgSQL</application>, you must build the utility
command as a string and then <command>EXECUTE</command> it, as
discussed in <xref linkend="plpgsql-statements-executing-dyn"/>.
最適化可能ではないSQLコマンド(ユーティリティコマンドとも呼ばれます)は問い合わせパラメータを受け付けられません。
そのため、PL/pgSQL変数の自動置換はそのようなコマンド内では機能しません。
PL/pgSQLから実行されるユーティリティコマンドに不変ではないテキストを含めるには、41.5.4で述べたように、ユーティリティコマンドを文字列として構築し、それをEXECUTE
しなければなりません。
<command>EXECUTE</command> must also be used if you want to modify
the command in some other way than supplying a data value, for example
by changing a table name.
例えば、テーブル名を変更するなど、データ値を提供する以外の方法でコマンドを修正したい場合にも、EXECUTE
を使わなければなりません。
Sometimes it is useful to evaluate an expression or <command>SELECT</command>
query but discard the result, for example when calling a function
that has side-effects but no useful result value. To do
this in <application>PL/pgSQL</application>, use the
<command>PERFORM</command> statement:
式またはSELECT
問い合わせを評価して結果を破棄することが、役に立つ場合があります。
例えば、関数の呼び出しにおいて、副次的な成果を取得できるが、結果は無用である場合です。
このような時PL/pgSQLでは、PERFORM
文を使用してください。
PERFORM query
;
This executes <replaceable>query</replaceable> and discards the
result. Write the <replaceable>query</replaceable> the same
way you would write an SQL <command>SELECT</command> command, but replace the
initial keyword <command>SELECT</command> with <command>PERFORM</command>.
For <command>WITH</command> queries, use <command>PERFORM</command> and then
place the query in parentheses. (In this case, the query can only
return one row.)
<application>PL/pgSQL</application> variables will be
substituted into the query just as described above,
and the plan is cached in the same way. Also, the special variable
<literal>FOUND</literal> is set to true if the query produced at
least one row, or false if it produced no rows (see
<xref linkend="plpgsql-statements-diagnostics"/>).
これはquery
を実行し、その結果を破棄します。
SQLのSELECT
文と同じ方法でquery
を記述しますが、最初のキーワードSELECT
をPERFORM
に置き換えてください。
WITH
問い合わせに対しては、PERFORM
を使用して、問い合わせをカッコ内に配置してください。
(この場合、問い合わせは1行だけ返すことができます。)
上述のように、PL/pgSQL変数は問い合わせ内に置き換えられ、計画は同様にキャッシュされます。
また、特殊な変数であるFOUND
は問い合わせ結果が1行でも生成された場合は真に設定され、生成されない場合は偽に設定されます(41.5.5を参照してください)。
One might expect that writing <command>SELECT</command> directly
would accomplish this result, but at
present the only accepted way to do it is
<command>PERFORM</command>. An SQL command that can return rows,
such as <command>SELECT</command>, will be rejected as an error
unless it has an <literal>INTO</literal> clause as discussed in the
next section.
直接SELECT
を記述すれば、この結果を得ることができると考えるかもしれませんが、現時点でこれを行う方法はPERFORM
しかありません。
SELECT
のように行を返すSQLコマンドは、エラーとして拒絶されます。
なお、INTO
句を有する時は例外であり、次節で説明します。
An example: 以下に例を示します。
PERFORM create_mv('cs_session_page_requests_mv', my_query);
The result of an SQL command yielding a single row (possibly of multiple
columns) can be assigned to a record variable, row-type variable, or list
of scalar variables. This is done by writing the base SQL command and
adding an <literal>INTO</literal> clause. For example,
(多分、複数列の)1行を返すSQLコマンドの結果は、レコード変数、行型の変数、スカラ変数のリストに代入することができます。
これは、基本的なSQLコマンドを記述して、それにINTO
句を追加することによって行われます。
以下に例を示します。
SELECTselect_expressions
INTO [STRICT]target
FROM ...; INSERT ... RETURNINGexpressions
INTO [STRICT]target
; UPDATE ... RETURNINGexpressions
INTO [STRICT]target
; DELETE ... RETURNINGexpressions
INTO [STRICT]target
; MERGE ... RETURNINGexpressions
INTO [STRICT]target
;
where <replaceable>target</replaceable> can be a record variable, a row
variable, or a comma-separated list of simple variables and
record/row fields.
<application>PL/pgSQL</application> variables will be
substituted into the rest of the command (that is, everything but the
<literal>INTO</literal> clause) just as described above,
and the plan is cached in the same way.
This works for <command>SELECT</command>,
<command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>/<command>MERGE</command>
with <literal>RETURNING</literal>, and certain utility commands
that return row sets, such as <command>EXPLAIN</command>.
Except for the <literal>INTO</literal> clause, the SQL command is the same
as it would be written outside <application>PL/pgSQL</application>.
《マッチ度[88.604353]》ここで、target
はレコード変数、行変数、あるいは、単純な変数とレコード/行変数のフィールドをカンマで区切ったリストです。
上述のようにPL/pgSQL変数によりコマンドの残り(すなわち、INTO
句以外のすべて)が置換され、同じように計画がキャッシュされます。
このように作動するのは、SELECT
、RETURNING
を伴ったINSERT
/UPDATE
/DELETE
とおよびEXPLAIN
のような行セットの結果を返す特定のユーティリティコマンドです。
INTO
句以外では、SQLコマンドはPL/pgSQLの外部に記述したものと同じです。
《機械翻訳》ここでtarget
はレコード変数、行変数、または単純な変数とレコード/行フィールドのカンマ区切りリストです。
上記のように、PL/pgSQL変数はコマンドの残りの部分(つまりINTO
句以外の部分)に置換され、計画は同じ方法でキャッシュされます。
これはSELECT
、INSERT
/UPDATE
/DELETE
/MERGE
、RETURNING
を伴う特定のユーティリティコマンド、および行セットを返すEXPLAIN
などに有効です。
INTO
句を除き、SQLコマンドはPL/pgSQLの外部で書かれた場合と同じです。
Note that this interpretation of <command>SELECT</command> with <literal>INTO</literal>
is quite different from <productname>PostgreSQL</productname>'s regular
<command>SELECT INTO</command> command, wherein the <literal>INTO</literal>
target is a newly created table. If you want to create a table from a
<command>SELECT</command> result inside a
<application>PL/pgSQL</application> function, use the syntax
<command>CREATE TABLE ... AS SELECT</command>.
通常のPostgreSQLのSELECT INTO
文では、INTO
の対象は新しく作成されるテーブルです。
しかし、INTO
を伴ったSELECT
では、この解釈が通常と大きく異なることに注意してください。
PL/pgSQL関数内部でSELECT
の結果からテーブルを作成したい場合は、CREATE TABLE ... AS SELECT
構文を使用してください。
If a row variable or a variable list is used as target, the command's result columns must exactly match the structure of the target as to number and data types, or else a run-time error occurs. When a record variable is the target, it automatically configures itself to the row type of the command's result columns. 行変数または変数リストが対象に使用された場合、列数とデータ型においてコマンドの結果と対象の構造が正確に一致しなければなりません。 さもないと、実行時エラーが発生します。 レコード変数が対象の場合は、コマンドの結果の列の行型に自身を自動的に設定します。
The <literal>INTO</literal> clause can appear almost anywhere in the SQL
command. Customarily it is written either just before or just after
the list of <replaceable>select_expressions</replaceable> in a
<command>SELECT</command> command, or at the end of the command for other
command types. It is recommended that you follow this convention
in case the <application>PL/pgSQL</application> parser becomes
stricter in future versions.
INTO
句はSQLコマンドのほとんど任意の場所に記述することができます。
習慣的には、SELECT
文においてはselect_expressions
の直前または直後に、他のコマンドにおいては文の終わりに記述されます。
将来のバージョンでPL/pgSQLのパーサがより厳格になる場合に備えて、この習慣に従うことを推奨します。
If <literal>STRICT</literal> is not specified in the <literal>INTO</literal>
clause, then <replaceable>target</replaceable> will be set to the first
row returned by the command, or to nulls if the command returned no rows.
(Note that <quote>the first row</quote> is not
well-defined unless you've used <literal>ORDER BY</literal>.) Any result rows
after the first row are discarded.
You can check the special <literal>FOUND</literal> variable (see
<xref linkend="plpgsql-statements-diagnostics"/>) to
determine whether a row was returned:
INTO
句においてSTRICT
が指定されない場合、target
はコマンドが返す最初の行となり、コマンドが行を返さない時はNULLとなります。
(「最初の行」とはORDER BY
を使用しないと定義できないことに注意してください。)
2行目以降の行の結果は、全て破棄されます。
以下のように、特殊なFOUND
変数(41.5.5を参照してください)を調べて、行が返されたかどうかを検査することができます。
SELECT * INTO myrec FROM emp WHERE empname = myname; IF NOT FOUND THEN RAISE EXCEPTION 'employee % not found', myname; END IF;
If the <literal>STRICT</literal> option is specified, the command must
return exactly one row or a run-time error will be reported, either
<literal>NO_DATA_FOUND</literal> (no rows) or <literal>TOO_MANY_ROWS</literal>
(more than one row). You can use an exception block if you wish
to catch the error, for example:
STRICT
オプションが指定された場合、コマンドは正確に1行を返さなければなりません。
さもないと、行がない時はNO_DATA_FOUND
、2行以上が返った時はTOO_MANY_ROWS
という実行時エラーが生じます。
エラーを捕捉したい時は、例外ブロックを使用できます。
以下に例を示します。
BEGIN SELECT * INTO STRICT myrec FROM emp WHERE empname = myname; EXCEPTION WHEN NO_DATA_FOUND THEN RAISE EXCEPTION 'employee % not found', myname; WHEN TOO_MANY_ROWS THEN RAISE EXCEPTION 'employee % not unique', myname; END;
Successful execution of a command with <literal>STRICT</literal>
always sets <literal>FOUND</literal> to true.
STRICT
を指定したコマンドが成功すると、FOUND
変数は常に真に設定されます。
For <command>INSERT</command>/<command>UPDATE</command>/<command>DELETE</command>/<command>MERGE</command> with
<literal>RETURNING</literal>, <application>PL/pgSQL</application> reports
an error for more than one returned row, even when
<literal>STRICT</literal> is not specified. This is because there
is no option such as <literal>ORDER BY</literal> with which to determine
which affected row should be returned.
《マッチ度[86.714976]》PL/pgSQLはSTRICT
が指定されない場合でも、RETURNING
を伴ったINSERT
/UPDATE
/DELETE
が2行以上を返した時は、エラーとなります。
なぜなら、どの1行を返すか決定するORDER BY
のようなオプションが存在しないからです。
《機械翻訳》RETURNING
を指定したINSERT
/UPDATE
/DELETE
/MERGE
に対して、STRICT
が指定されていない場合でも、PL/pgSQLは複数の返された行に対してエラーを報告します。
これは、どの返された行を返すかを決定するためのORDER BY
などのオプションがないためです。
If <literal>print_strict_params</literal> is enabled for the function,
then when an error is thrown because the requirements
of <literal>STRICT</literal> are not met, the <literal>DETAIL</literal> part of
the error message will include information about the parameters
passed to the command.
You can change the <literal>print_strict_params</literal>
setting for all functions by setting
<varname>plpgsql.print_strict_params</varname>, though only subsequent
function compilations will be affected. You can also enable it
on a per-function basis by using a compiler option, for example:
print_strict_params
が関数に利用可能であり、かつ要求がSTRICT
でないためにエラーが発生した場合、エラーメッセージのDETAIL
部分はコマンドに渡したパラメータに関する情報を含みます。
plpgsql.print_strict_params
を指定することにより、全ての関数のprint_strict_params
設定を変更できます。
しかし、変更後にコンパイルした関数にだけ有効です。
コンパイルオプションを使用すれば、個々の関数を基準とした設定変更もできます。
例を示します。
CREATE FUNCTION get_userid(username text) RETURNS int AS $$ #print_strict_params on DECLARE userid int; BEGIN SELECT users.userid INTO STRICT userid FROM users WHERE users.username = get_userid.username; RETURN userid; END; $$ LANGUAGE plpgsql;
On failure, this function might produce an error message such as 失敗したとき、この関数は次のようなエラーメッセージを生成します。
ERROR: query returned no rows DETAIL: parameters: username = 'nosuchuser' CONTEXT: PL/pgSQL function get_userid(text) line 6 at SQL statement
The <literal>STRICT</literal> option matches the behavior of
Oracle PL/SQL's <command>SELECT INTO</command> and related statements.
STRICT
オプションは、OracleのPL/SQLのSELECT INTO
および関連した文に対応します。
Oftentimes you will want to generate dynamic commands inside your
<application>PL/pgSQL</application> functions, that is, commands
that will involve different tables or different data types each
time they are executed. <application>PL/pgSQL</application>'s
normal attempts to cache plans for commands (as discussed in
<xref linkend="plpgsql-plan-caching"/>) will not work in such
scenarios. To handle this sort of problem, the
<command>EXECUTE</command> statement is provided:
PL/pgSQL関数の内部で、動的コマンド、つまり実行する度に別のテーブルや別のデータ型を使用するコマンドを生成したいということがよくあるでしょう。
PL/pgSQLが通常行うコマンドの計画のキャッシュは(41.11.2で述べたように)このような状況では動作しません。
この種の問題を扱うために、以下のEXECUTE
文が用意されています。
EXECUTEcommand-string
[ INTO [STRICT]target
] [ USINGexpression
[, ... ] ];
where <replaceable>command-string</replaceable> is an expression
yielding a string (of type <type>text</type>) containing the
command to be executed. The optional <replaceable>target</replaceable>
is a record variable, a row variable, or a comma-separated list of
simple variables and record/row fields, into which the results of
the command will be stored. The optional <literal>USING</literal> expressions
supply values to be inserted into the command.
ここで、command-string
は実行されるコマンドを含む(text
型の)文字列を生成する式です。
オプションのtarget
はレコード変数、行変数、あるいは、単純な変数とレコード/行変数のフィールドをカンマで区切ったリストで、その中にコマンドの結果が格納されます。
オプションのUSING
式は コマンドに挿入される値を与えます。
No substitution of <application>PL/pgSQL</application> variables is done on the computed command string. Any required variable values must be inserted in the command string as it is constructed; or you can use parameters as described below. PL/pgSQL変数は、この演算用のコマンド文字列へ置換されません。 必要な変数の値はすべてコマンド文字列を作成する時に埋め込まなければなりません。 もしくは、以下に説明するパラメータを使用することもできます。
Also, there is no plan caching for commands executed via
<command>EXECUTE</command>. Instead, the command is always planned
each time the statement is run. Thus the command
string can be dynamically created within the function to perform
actions on different tables and columns.
また、EXECUTE
を介して実行されるコマンド計画をキャッシュすることはありません。
代わりに、コマンドは文が実行されるとき常に計画されます。
したがって、異なるテーブルと列に対する操作を実行できるように、コマンド文字列を関数内部で動的に作成することができます。
The <literal>INTO</literal> clause specifies where the results of
an SQL command returning rows should be assigned. If a row variable
or variable list is provided, it must exactly match the structure
of the command's results; if a
record variable is provided, it will configure itself to match the
result structure automatically. If multiple rows are returned,
only the first will be assigned to the <literal>INTO</literal>
variable(s). If no rows are returned, NULL is assigned to the
<literal>INTO</literal> variable(s). If no <literal>INTO</literal>
clause is specified, the command results are discarded.
INTO
句は、行を返すSQLコマンドの結果を代入するべき場所を指定します。
行変数または変数リストが用いられる時、それはコマンドの結果の構造と正確に一致しなければなりません。レコード変数が使用される時、自動的に結果の構造と一致するように自身を構築させます。
複数の行が返された時、最初の行だけがINTO
変数に代入されます。
1行も返されない時、NULLがINTO
変数に代入されます。
INTO
句が指定されない時、コマンドの結果は捨てられます。
If the <literal>STRICT</literal> option is given, an error is reported
unless the command produces exactly one row.
STRICT
オプションが指定された時、コマンドの結果が正確に1行の場合を除き、エラーとなります。
The command string can use parameter values, which are referenced
in the command as <literal>$1</literal>, <literal>$2</literal>, etc.
These symbols refer to values supplied in the <literal>USING</literal>
clause. This method is often preferable to inserting data values
into the command string as text: it avoids run-time overhead of
converting the values to text and back, and it is much less prone
to SQL-injection attacks since there is no need for quoting or escaping.
An example is:
コマンド文字列はパラメータ値を使用可能で、それらは$1
、$2
等としてコマンドの中で参照されます。
これらの記号はUSING
で与えられる値を参照します。
この方式はデータの値をテキストとしてコマンド文字列の中に挿入する際、よく好まれます。
それは値をテキストに変換、そしてその逆を行う場合の実行時オーバーヘッドを防止するとともに、引用符付けするとか、エスケープをする必要がないため、SQLインジェクション攻撃に対してより襲われにくくなります。
以下に例を示します。
EXECUTE 'SELECT count(*) FROM mytable WHERE inserted_by = $1 AND inserted <= $2' INTO c USING checked_user, checked_date;
Note that parameter symbols can only be used for data values — if you want to use dynamically determined table or column names, you must insert them into the command string textually. For example, if the preceding query needed to be done against a dynamically selected table, you could do this: パラメータ記号はデータ値のみ使用可能です。 もし動的に決定されるテーブルや列名を使用したい場合、テキストでコマンド文字列にそれらを挿入する必要があります。 例えば、先行する問い合わせが、動的に選択されたテーブルに対して処理される必要がある時は、次のようにします。
EXECUTE 'SELECT count(*) FROM ' || quote_ident(tabname) || ' WHERE inserted_by = $1 AND inserted <= $2' INTO c USING checked_user, checked_date;
A cleaner approach is to use <function>format()</function>'s <literal>%I</literal>
specification to insert table or column names with automatic quoting:
よりきれいな方法は、format()
の%I
指定を使い自動引用符付けされたテーブル名または列名を挿入することです。
EXECUTE format('SELECT count(*) FROM %I ' 'WHERE inserted_by = $1 AND inserted <= $2', tabname) INTO c USING checked_user, checked_date;
(This example relies on the SQL rule that string literals separated by a newline are implicitly concatenated.) (この例は、改行により分割された文字列リテラルが暗黙に連結されるというSQL規則に依存しています。)
Another restriction on parameter symbols is that they only work in
optimizable SQL commands
(<command>SELECT</command>, <command>INSERT</command>, <command>UPDATE</command>,
<command>DELETE</command>, <command>MERGE</command>, and certain commands containing one of these).
In other statement
types (generically called utility statements), you must insert
values textually even if they are just data values.
他にもパラメータ記号は最適化可能なSQLコマンド(SELECT
、INSERT
、UPDATE
、DELETE
、MERGE
、およびこのうちの1つを含む特定のコマンド)でしか動作しない、という制限があります。
他の種類の文(一般的にユーティリティ文と呼ばれます)では、単なるデータ値であったとしてもテキストの値として埋め込まなければなりません。
An <command>EXECUTE</command> with a simple constant command string and some
<literal>USING</literal> parameters, as in the first example above, is
functionally equivalent to just writing the command directly in
<application>PL/pgSQL</application> and allowing replacement of
<application>PL/pgSQL</application> variables to happen automatically.
The important difference is that <command>EXECUTE</command> will re-plan
the command on each execution, generating a plan that is specific
to the current parameter values; whereas
<application>PL/pgSQL</application> may otherwise create a generic plan
and cache it for re-use. In situations where the best plan depends
strongly on the parameter values, it can be helpful to use
<command>EXECUTE</command> to positively ensure that a generic plan is not
selected.
最初の例のように、単純な定数コマンドとUSING
パラメータを使ったEXECUTE
は、コマンドを直接PL/pgSQLで書いて、PL/pgSQL変数を自動的に置換したものと機能的に同じです。
重要な差異として、EXECUTE
が現在のパラメータ値に特化した計画を生成し、コマンドを実行する度に計画を再作成することです。
一方、PL/pgSQLはその他に汎用的な計画を作成し、再使用に備えキャッシュします。
最適な計画がパラメータ値に大きく依存する場合、汎用的な計画が選択されないことを確保するために、EXECUTE
の使用は助けになります。
<command>SELECT INTO</command> is not currently supported within
<command>EXECUTE</command>; instead, execute a plain <command>SELECT</command>
command and specify <literal>INTO</literal> as part of the <command>EXECUTE</command>
itself.
SELECT INTO
はEXECUTE
では現在サポートされません。
代わりに、普通のSELECT
コマンドを実行し、EXECUTE
の一部としてINTO
を記述してください。
The <application>PL/pgSQL</application>
<command>EXECUTE</command> statement is not related to the
<link linkend="sql-execute"><command>EXECUTE</command></link> SQL
statement supported by the
<productname>PostgreSQL</productname> server. The server's
<command>EXECUTE</command> statement cannot be used directly within
<application>PL/pgSQL</application> functions (and is not needed).
PL/pgSQL EXECUTE
文はPostgreSQLサーバでサポートされているEXECUTE
SQL文とは関連がありません。
サーバのEXECUTE
文はPL/pgSQL関数内で使用することはできません(使用する必要もありません)。
例41.1 動的問い合わせの中の値の引用符付け
When working with dynamic commands you will often have to handle escaping of single quotes. The recommended method for quoting fixed text in your function body is dollar quoting. (If you have legacy code that does not use dollar quoting, please refer to the overview in <xref linkend="plpgsql-quote-tips"/>, which can save you some effort when translating said code to a more reasonable scheme.) 動的コマンドを使用する時、しばしば単一引用符をエスケープしなければなりません。 関数本体における固定のテキストを引用符付けする推奨方法は、ドル引用符を使用する方法です。 (ドル引用符を用いない旧式のコードを保有している場合は、41.12.1の概要を参照することが、理解しやすいコードへの変換作業の手助けになります)。
Dynamic values require careful handling since they might contain
quote characters.
An example using <function>format()</function> (this assumes that you are
dollar quoting the function body so quote marks need not be doubled):
動的な値は引用符を含んでいる可能性があるので注意深い取り扱いが必要です。
以下にformat()
を使う例を示します(ここでは関数にドル引用符を用いる方法を使用すると仮定しているので、引用符を二重化する必要はありません)。
EXECUTE format('UPDATE tbl SET %I = $1 ' 'WHERE key = $2', colname) USING newvalue, keyvalue;
It is also possible to call the quoting functions directly: クオート関数を直接呼び出すことも可能です。
EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) || ' = ' || quote_literal(newvalue) || ' WHERE key = ' || quote_literal(keyvalue);
This example demonstrates the use of the
<function>quote_ident</function> and
<function>quote_literal</function> functions (see <xref
linkend="functions-string"/>). For safety, expressions containing column
or table identifiers should be passed through
<function>quote_ident</function> before insertion in a dynamic query.
Expressions containing values that should be literal strings in the
constructed command should be passed through <function>quote_literal</function>.
These functions take the appropriate steps to return the input text
enclosed in double or single quotes respectively, with any embedded
special characters properly escaped.
この例は、quote_ident
とquote_literal
関数(9.4を参照)の使用方法を示しています。
安全のため、列またはテーブル識別子を含む式は動的問い合わせに挿入する前にquote_ident
を介して渡されなくてはなりません。
組み立てられるコマンドの中のリテラル文字列となるはずの値を含む式は、quote_literal
を介して渡されなければなりません。
これらの関数は、すべての特殊文字を適切にエスケープして埋め込んだ、二重引用符または単一引用符で囲まれた入力テキストを返すために、適切な手順を踏みます。
Because <function>quote_literal</function> is labeled
<literal>STRICT</literal>, it will always return null when called with a
null argument. In the above example, if <literal>newvalue</literal> or
<literal>keyvalue</literal> were null, the entire dynamic query string would
become null, leading to an error from <command>EXECUTE</command>.
You can avoid this problem by using the <function>quote_nullable</function>
function, which works the same as <function>quote_literal</function> except that
when called with a null argument it returns the string <literal>NULL</literal>.
For example,
quote_literal
はSTRICT
ラベル付けされているため、NULL引数で呼び出された場合、常にNULLを返します。
上記の例で、newvalue
またはkeyvalue
がNULLの場合、動的問合せ文字列全体がNULLとなり、EXECUTE
からのエラーを導きます。
quote_nullable
関数を使用することで、この問題を回避することができます。
その動作は、NULL引数付きで呼び出された場合に文字列NULL
を返すことを除いてquote_literal
と同一です。
以下に例を示します。
EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) || ' = ' || quote_nullable(newvalue) || ' WHERE key = ' || quote_nullable(keyvalue);
If you are dealing with values that might be null, you should usually
use <function>quote_nullable</function> in place of <function>quote_literal</function>.
NULLの可能性のある値を処理するのであれば、通常quote_literal
の代わりにquote_nullable
を使用しなければなりません。
As always, care must be taken to ensure that null values in a query do
not deliver unintended results. For example the <literal>WHERE</literal> clause
いつものように、問い合わせの中のNULL値は意図しない結果を確実にもたらさないよう配慮をしなければなりません。
例えば次のようなWHERE
句の結果はどうなるのでしょう。
'WHERE key = ' || quote_nullable(keyvalue)
will never succeed if <literal>keyvalue</literal> is null, because the
result of using the equality operator <literal>=</literal> with a null operand
is always null. If you wish null to work like an ordinary key value,
you would need to rewrite the above as
これはkeyvalue
がNULLである限り成功しません。
その理由は、等価演算子=
をNULLオペランドで使用するとその結果は常にNULLとなるからです。
NULLを通常のキーの値と同じように動作させたい場合、上記を、以下のように書き換えなければなりません。
'WHERE key IS NOT DISTINCT FROM ' || quote_nullable(keyvalue)
(At present, <literal>IS NOT DISTINCT FROM</literal> is handled much less
efficiently than <literal>=</literal>, so don't do this unless you must.
See <xref linkend="functions-comparison"/> for
more information on nulls and <literal>IS DISTINCT</literal>.)
(現時点では、IS NOT DISTINCT FROM
は=
よりもより効率性が少なく扱われますので、必要に迫られた場合以外は行わないようにしてください。
NULLとIS DISTINCT
についての更なる情報は9.2を参照してください。)
Note that dollar quoting is only useful for quoting fixed text. It would be a very bad idea to try to write this example as: ドル引用符は固定のテキストを引用符付けする場合のみ有用であるということに注意してください。 この例を次のように記述するのは非常に悪い考えです。
EXECUTE 'UPDATE tbl SET ' || quote_ident(colname) || ' = $$' || newvalue || '$$ WHERE key = ' || quote_literal(keyvalue);
because it would break if the contents of <literal>newvalue</literal>
happened to contain <literal>$$</literal>. The same objection would
apply to any other dollar-quoting delimiter you might pick.
So, to safely quote text that is not known in advance, you
<emphasis>must</emphasis> use <function>quote_literal</function>,
<function>quote_nullable</function>, or <function>quote_ident</function>, as appropriate.
なぜなら、newvalue
の内容がたまたま$$
を含む時は、途中で次の処理へ移ってしまうからです。
同様の不測事態は、ドル引用符の他の区切り文字を選んだ時も起こります。
したがって、テキストの内容を把握していない時は、安全にテキストを引用符付けするために、quote_literal
、quote_nullable
、またはquote_ident
関数を適切に使用しなければなりません。
Dynamic SQL statements can also be safely constructed using the
<function>format</function> function (see <xref
linkend="functions-string-format"/>). For example:
動的なSQL文もformat
関数(9.4.1を参照)を使って安全に作ることができます。例を示します。
EXECUTE format('UPDATE tbl SET %I = %L ' 'WHERE key = %L', colname, newvalue, keyvalue);
<literal>%I</literal> is equivalent to <function>quote_ident</function>, and
<literal>%L</literal> is equivalent to <function>quote_nullable</function>.
The <function>format</function> function can be used in conjunction with
the <literal>USING</literal> clause:
%I
はquote_ident
と同等で、%L
はquote_nullable
と同等です。
format
関数はUSING
句と共に使用できます。
EXECUTE format('UPDATE tbl SET %I = $1 WHERE key = $2', colname) USING newvalue, keyvalue;
This form is better because the variables are handled in their native
data type format, rather than unconditionally converting them to
text and quoting them via <literal>%L</literal>. It is also more efficient.
変数が、無条件にテキストに変換されて%L
で引用符付けされることなく、固有のデータ形式で処理されるため、この形式はより優れています。
A much larger example of a dynamic command and
<command>EXECUTE</command> can be seen in <xref
linkend="plpgsql-porting-ex2"/>, which builds and executes a
<command>CREATE FUNCTION</command> command to define a new function.
動的問い合わせとEXECUTE
の長大な例は例 41.10にあります。
それは新しい関数を定義するためにCREATE FUNCTION
コマンドを組み立て実行するものです。
There are several ways to determine the effect of a command. The
first method is to use the <command>GET DIAGNOSTICS</command>
command, which has the form:
コマンドの効果を判断するにはいくつか方法があります。
最初の方法は以下のような形式のGET DIAGNOSTICS
を使用する方法です。
GET [ CURRENT ] DIAGNOSTICSvariable
{ = | := }item
[ , ... ];
This command allows retrieval of system status indicators.
<literal>CURRENT</literal> is a noise word (but see also <command>GET STACKED
DIAGNOSTICS</command> in <xref linkend="plpgsql-exception-diagnostics"/>).
Each <replaceable>item</replaceable> is a key word identifying a status
value to be assigned to the specified <replaceable>variable</replaceable>
(which should be of the right data type to receive it). The currently
available status items are shown
in <xref linkend="plpgsql-current-diagnostics-values"/>. Colon-equal
(<literal>:=</literal>) can be used instead of the SQL-standard <literal>=</literal>
token. An example:
このコマンドによってシステムステータスインジケータを取り出すことができます。
CURRENT
は無意味な単語です(しかし41.6.8.1のGET STACKED DIAGNOSTICS
も参照してください)。
各item
は、指定されたvariable
(これは受け取るために正しいデータ型でなければなりません)に代入されるステータス値を識別するキーワードです。
現在使用可能なステータス項目は、表 41.1で示されています。
代入記号(:=
)が標準SQLにおける等号(=
)の代わりに使用できます。
以下に例を示します。
GET DIAGNOSTICS integer_var = ROW_COUNT;
表41.1 使用できるステータス項目
名前 | 型 | 説明 |
---|---|---|
ROW_COUNT | bigint | 最後のSQLコマンドにより処理された行数 |
PG_CONTEXT | text | 現在の呼び出しスタックを記述したテキストの行 (41.6.9を参照) |
PG_ROUTINE_OID | oid | 現在の関数のOID |
The second method to determine the effects of a command is to check the
special variable named <literal>FOUND</literal>, which is of
type <type>boolean</type>. <literal>FOUND</literal> starts out
false within each <application>PL/pgSQL</application> function call.
It is set by each of the following types of statements:
コマンドの効果を判断する2番目の方法は、FOUND
というboolean
型の特殊な変数を検査することです。
PL/pgSQLの各関数呼び出しで使用される際、FOUND
は最初は偽に設定されています。
以下のように、それぞれの文の種類によって設定が変更されます。
A <command>SELECT INTO</command> statement sets
<literal>FOUND</literal> true if a row is assigned, false if no
row is returned.
SELECT INTO
文は、行が代入された場合は真、返されなかった場合は偽をFOUND
に設定します。
A <command>PERFORM</command> statement sets <literal>FOUND</literal>
true if it produces (and discards) one or more rows, false if
no row is produced.
PERFORM
文は、1つ以上の行が生成(破棄)された場合は真、まったく生成されなかった場合は偽をFOUND
に設定します。
<command>UPDATE</command>, <command>INSERT</command>, <command>DELETE</command>,
and <command>MERGE</command>
statements set <literal>FOUND</literal> true if at least one
row is affected, false if no row is affected.
UPDATE
、INSERT
、DELETE
、およびMERGE
文は、少なくとも1行が影響を受けた場合は真、まったく影響を受けなかった場合は偽をFOUND
に設定します。
A <command>FETCH</command> statement sets <literal>FOUND</literal>
true if it returns a row, false if no row is returned.
FETCH
文は、行が返された場合は真、まったく返されなかった場合は偽をFOUND
に設定します。
A <command>MOVE</command> statement sets <literal>FOUND</literal>
true if it successfully repositions the cursor, false otherwise.
MOVE
文は、カーソルの移動が成功した場合は真、失敗した場合は偽をFOUND
に設定します。
A <command>FOR</command> or <command>FOREACH</command> statement sets
<literal>FOUND</literal> true
if it iterates one or more times, else false.
<literal>FOUND</literal> is set this way when the
loop exits; inside the execution of the loop,
<literal>FOUND</literal> is not modified by the
loop statement, although it might be changed by the
execution of other statements within the loop body.
FOR
文またはFOREACH
文は、1回以上繰り返しが行われた場合は真、行われなかった場合は偽をFOUND
に設定します。
FOUND
はループが終了した際、このように設定されます。
ループ実行中はループ文によるFOUND
の変更はありません。
ただし、ループ本体内の他種類の文を実行することによって、変更されるかもしれません。
<command>RETURN QUERY</command> and <command>RETURN QUERY
EXECUTE</command> statements set <literal>FOUND</literal>
true if the query returns at least one row, false if no row
is returned.
RETURN QUERY
とRETURN QUERY EXECUTE
文は、問い合わせが行を1つでも返せば真、行が返されなければ偽をFOUND
に設定します。
Other <application>PL/pgSQL</application> statements do not change
the state of <literal>FOUND</literal>.
Note in particular that <command>EXECUTE</command>
changes the output of <command>GET DIAGNOSTICS</command>, but
does not change <literal>FOUND</literal>.
他のPL/pgSQL文はFOUND
の状態を変更しません。
特に、EXECUTE
はGET DIAGNOSTICS
の出力を変更しますが、FOUND
を変更しないことに注意してください。
<literal>FOUND</literal> is a local variable within each
<application>PL/pgSQL</application> function; any changes to it
affect only the current function.
FOUND
はそれぞれのPL/pgSQL関数内部のローカル変数です。
FOUND
に対して行われた全ての変更は、現在の関数にのみ影響します。
Sometimes a placeholder statement that does nothing is useful.
For example, it can indicate that one arm of an if/then/else
chain is deliberately empty. For this purpose, use the
<command>NULL</command> statement:
何もしないプレースホルダ文が有用になることがあります。
例えば、IF/THEN/ELSE文の一部が空文であることを明示したい時です。
このような目的にはNULL
文を使用します。
NULL;
For example, the following two fragments of code are equivalent: 例えば、次の2つのコードは同等です。
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN
NULL; -- ignore the error
NULL; -- 誤りを無視する
END;
BEGIN
y := x / 0;
EXCEPTION
WHEN division_by_zero THEN -- ignore the error
WHEN division_by_zero THEN -- 誤りを無視する
END;
Which is preferable is a matter of taste. どちらが望ましいと思うかは、好みの問題です。
In Oracle's PL/SQL, empty statement lists are not allowed, and so
<command>NULL</command> statements are <emphasis>required</emphasis> for situations
such as this. <application>PL/pgSQL</application> allows you to
just write nothing, instead.
OracleのPL/SQLでは無記述の文は許されませんので、こうした状況ではNULL
文が必須です。
しかしPL/pgSQLでは無記述の文が許可されています。