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

44.5. PL/Tclからのデータベースアクセス #

<title>Database Access from PL/Tcl</title>

In this section, we follow the usual Tcl convention of using question marks, rather than brackets, to indicate an optional element in a syntax synopsis. The following commands are available to access the database from the body of a PL/Tcl function: この節では、通常のTclの規約に従い、構文の概要でオプションの要素を示すのに角括弧ではなく疑問符を使います。 下記のコマンドは、PL/Tcl関数内からデータベースアクセスを行う時に使用できるコマンドです。

spi_exec ?-count n? ?-array name? command ?loop-body?

Executes an SQL command given as a string. An error in the command causes an error to be raised. Otherwise, the return value of <function>spi_exec</function> is the number of rows processed (selected, inserted, updated, or deleted) by the command, or zero if the command is a utility statement. In addition, if the command is a <command>SELECT</command> statement, the values of the selected columns are placed in Tcl variables as described below. 文字列として与えられたSQL問い合わせを実行します。 コマンド内のエラーは、エラーの発生となります。 さもなければ、このspi_execの戻り値はコマンドによって処理(選択、挿入、更新、削除)された行数、または、コマンドがユーティリティ文の場合はゼロとなります。 さらに、コマンドがSELECT文の場合、選択された列の値は以下のようにTclの変数に格納されます。

The optional <literal>-count</literal> value tells <function>spi_exec</function> to stop once <replaceable>n</replaceable> rows have been retrieved, much as if the query included a <literal>LIMIT</literal> clause. If <replaceable>n</replaceable> is zero, the query is run to completion, the same as when <literal>-count</literal> is omitted. オプションの-count値は、spi_execに対し、問い合わせにLIMIT句が含まれているかのように、n行を取得すると停止するよう指示します。 nが0の場合、問い合わせは完了するまで実行されます。これは、-countが省略された場合と同じです。

If the command is a <command>SELECT</command> statement, the values of the result columns are placed into Tcl variables named after the columns. If the <literal>-array</literal> option is given, the column values are instead stored into elements of the named associative array, with the column names used as array indexes. In addition, the current row number within the result (counting from zero) is stored into the array element named <quote><literal>.tupno</literal></quote>, unless that name is in use as a column name in the result. コマンドがSELECT文の場合、その結果得られた列の値は、列名にちなんだ名前のTcl変数に格納されます。 -arrayオプションが付与された場合は、列の値は指定された名前の連想配列の要素に格納され、その配列のインデックスとして列名が使用されます。 加えて、結果内での現在の行番号(ゼロから数えます)が.tupnoという名前の配列要素に格納されます。ただし、その名前が結果内の列名として使われていない場合に限られます。

If the command is a <command>SELECT</command> statement and no <replaceable>loop-body</replaceable> script is given, then only the first row of results are stored into Tcl variables or array elements; remaining rows, if any, are ignored. No storing occurs if the query returns no rows. (This case can be detected by checking the result of <function>spi_exec</function>.) For example: 問い合わせ文がSELECT文、かつ、loop-bodyスクリプトが付与されなかった場合、結果のうち最初の行だけがTclの変数または配列要素に格納されます。 他にも行があったとしても、それらは無視されます。 問い合わせが行を返さなかった場合は、変数への格納は発生しません (spi_execの戻り値を検査することで、これを検出することができます)。 以下に例を示します。

spi_exec "SELECT count(*) AS cnt FROM pg_proc"

will set the Tcl variable <literal>$cnt</literal> to the number of rows in the <structname>pg_proc</structname> system catalog. これは、$cnt Tcl変数を、pg_procシステムカタログの行数に設定します。

If the optional <replaceable>loop-body</replaceable> argument is given, it is a piece of Tcl script that is executed once for each row in the query result. (<replaceable>loop-body</replaceable> is ignored if the given command is not a <command>SELECT</command>.) The values of the current row's columns are stored into Tcl variables or array elements before each iteration. For example: loop-bodyオプション引数が付与された場合、それは、問い合わせの結果内の行それぞれに対して一度だけ実行される小さなTclスクリプトです (loop-bodySELECT以外の問い合わせで付与された場合は無視されます)。 処理中の行の列値は、各繰り返しの前にTclの変数または配列要素に格納されます。 以下に例を示します。

spi_exec -array C "SELECT * FROM pg_class" {
    elog DEBUG "have table $C(relname)"
}

will print a log message for every row of <literal>pg_class</literal>. This feature works similarly to other Tcl looping constructs; in particular <literal>continue</literal> and <literal>break</literal> work in the usual way inside the loop body. これは、pg_classの各行に対してログメッセージを出力します。 この機能は他のTclの繰り返し構文でも同様に動作します。 特にループ本体内のcontinuebreakは通常通り動作します。

If a column of a query result is null, the target variable for it is <quote>unset</quote> rather than being set. 問い合わせの結果、列がNULLであった場合、対象となる変数は代入されずに、未設定状態になります。

spi_prepare query typelist

Prepares and saves a query plan for later execution. The saved plan will be retained for the life of the current session.<indexterm><primary>preparing a query</primary> <secondary>in PL/Tcl</secondary></indexterm> 後の実行のために問い合わせ計画の準備、保存を行います。 保存された計画は現在のセッションが終了するまで保持されます。

The query can use parameters, that is, placeholders for values to be supplied whenever the plan is actually executed. In the query string, refer to parameters by the symbols <literal>$1</literal> ... <literal>$<replaceable>n</replaceable></literal>. If the query uses parameters, the names of the parameter types must be given as a Tcl list. (Write an empty list for <replaceable>typelist</replaceable> if no parameters are used.) 問い合わせはパラメータ、つまり、計画が実際に実行される時に常に与えられる値用のプレースホルダを持つことができます。 問い合わせ文字列の中では、$1 ... $nというシンボルを使用して引数を参照してください。 問い合わせがパラメータを使用する場合、Tclのリストとしてパラメータの型名を指定する必要があります。 (パラメータを使用しない場合はtypelistには空のリストを指定してください。)

The return value from <function>spi_prepare</function> is a query ID to be used in subsequent calls to <function>spi_execp</function>. See <function>spi_execp</function> for an example. spi_prepareの戻り値は問い合わせIDです。 このIDは後にspi_execpを呼び出す時に使用されます。 使用例についてはspi_execpを参照してください。

spi_execp ?-count n? ?-array name? ?-nulls string? queryid ?value-list? ?loop-body?

Executes a query previously prepared with <function>spi_prepare</function>. <replaceable>queryid</replaceable> is the ID returned by <function>spi_prepare</function>. If the query references parameters, a <replaceable>value-list</replaceable> must be supplied. This is a Tcl list of actual values for the parameters. The list must be the same length as the parameter type list previously given to <function>spi_prepare</function>. Omit <replaceable>value-list</replaceable> if the query has no parameters. spi_prepareにより事前に準備された問い合わせを実行します。 queryidspi_prepareにより返されたIDです。 その問い合わせがパラメータを参照する場合、value-listを与える必要があります。 これは、そのパラメータの実際の値を持つTclのリストです。 このリストの長さは、事前にspi_prepareで指定した引数型のリストの長さと同じでなければなりません。 問い合わせにパラメータがない場合は、value-listを省略してください。

The optional value for <literal>-nulls</literal> is a string of spaces and <literal>'n'</literal> characters telling <function>spi_execp</function> which of the parameters are null values. If given, it must have exactly the same length as the <replaceable>value-list</replaceable>. If it is not given, all the parameter values are nonnull. -nullsオプションの値は、空白文字と'n'という文字からなる文字列で、spi_execpに対し、どの引数がNULL値かを示します。 指定された場合、その文字列の長さはvalue-listの長さと正確に一致していなければなりません。 指定されない場合は、すべてのパラメータの値は非NULLです。

Except for the way in which the query and its parameters are specified, <function>spi_execp</function> works just like <function>spi_exec</function>. The <literal>-count</literal>, <literal>-array</literal>, and <replaceable>loop-body</replaceable> options are the same, and so is the result value. 問い合わせとそのパラメータをどこで指定するのかという点を除き、spi_execpspi_execと同様に動作します。 -count-arrayloop-bodyオプションも、そして、結果の値も同じです。

Here's an example of a PL/Tcl function using a prepared plan: ここで、プリペアド計画を使用した、PL/Tcl関数の例を示します。

CREATE FUNCTION t1_count(integer, integer) RETURNS integer AS $$
    if {![ info exists GD(plan) ]} {

        # prepare the saved plan on the first call

        # 最初の呼び出しでは保存する計画を準備します。
        set GD(plan) [ spi_prepare \
                "SELECT count(*) AS cnt FROM t1 WHERE num >= \$1 AND num <= \$2" \
                [ list int4 int4 ] ]
    }
    spi_execp -count 1 $GD(plan) [ list $1 $2 ]
    return $cnt
$$ LANGUAGE pltcl;

We need backslashes inside the query string given to <function>spi_prepare</function> to ensure that the <literal>$<replaceable>n</replaceable></literal> markers will be passed through to <function>spi_prepare</function> as-is, and not replaced by Tcl variable substitution. spi_prepareに与える問い合わせ文字列の内側では、$n記号が確実にそのままspi_prepareに渡され、Tcl変数の代入による置き換えが起こらないようにバックスラッシュが必要です。

subtransaction command

The Tcl script contained in <replaceable>command</replaceable> is executed within an SQL subtransaction. If the script returns an error, that entire subtransaction is rolled back before returning the error out to the surrounding Tcl code. See <xref linkend="pltcl-subtransactions"/> for more details and an example. commandに含まれるTclスクリプトが、SQLサブトランザクション中で実行されます。 スクリプトがエラーを返すと、上位のTclコードにエラーを返す前に、そのサブトランザクションをロールバックします。 更なる詳細と使用例については44.9を参照してください。

quote string

Doubles all occurrences of single quote and backslash characters in the given string. This can be used to safely quote strings that are to be inserted into SQL commands given to <function>spi_exec</function> or <function>spi_prepare</function>. For example, think about an SQL command string like: 指定された文字列内のすべての単一引用符とバックスラッシュ文字を二重化します。 spi_execspi_prepareで与えられたSQL問い合わせに挿入される予定の文字列を安全に引用符付けするために、これを使用することができます。 例えば、以下のような問い合わせ文字列を考えます。

"SELECT '$val' AS ret"

where the Tcl variable <literal>val</literal> actually contains <literal>doesn't</literal>. This would result in the final command string: ここで、val Tcl変数にdoesn'tが実際に含まれているものとします。 これは最終的に以下の問い合わせ文字列になってしまいます。

SELECT 'doesn't' AS ret

which would cause a parse error during <function>spi_exec</function> or <function>spi_prepare</function>. To work properly, the submitted command should contain: これでは、spi_execまたはspi_prepareの実行中に解析エラーが発生してしまいます。 正しく稼働させるには、実行したい問い合わせは以下のようにしなければなりません。

SELECT 'doesn''t' AS ret

which can be formed in PL/Tcl using: これは、PL/Tclでは以下により形成することができます。

"SELECT '[ quote $val ]' AS ret"

One advantage of <function>spi_execp</function> is that you don't have to quote parameter values like this, since the parameters are never parsed as part of an SQL command string. spi_execpの持つ1つの利点は、パラメータはSQL問い合わせ文字列の一部として解析されることがありませんので、このようにパラメータの値を引用符付けする必要がないことです。

elog level msg

Emits a log or error message. Possible levels are <literal>DEBUG</literal>, <literal>LOG</literal>, <literal>INFO</literal>, <literal>NOTICE</literal>, <literal>WARNING</literal>, <literal>ERROR</literal>, and <literal>FATAL</literal>. <literal>ERROR</literal> raises an error condition; if this is not trapped by the surrounding Tcl code, the error propagates out to the calling query, causing the current transaction or subtransaction to be aborted. This is effectively the same as the Tcl <literal>error</literal> command. <literal>FATAL</literal> aborts the transaction and causes the current session to shut down. (There is probably no good reason to use this error level in PL/Tcl functions, but it's provided for completeness.) The other levels only generate messages of different priority levels. Whether messages of a particular priority are reported to the client, written to the server log, or both is controlled by the <xref linkend="guc-log-min-messages"/> and <xref linkend="guc-client-min-messages"/> configuration variables. See <xref linkend="runtime-config"/> and <xref linkend="pltcl-error-handling"/> for more information. ログまたはエラーメッセージを発行します。 使用できるレベルは、DEBUGLOGINFONOTICEWARNINGERROR、およびFATALです。 ERRORはエラー状態を発生します。 その上位レベルのTclコードで例外が捕捉されなければ、このエラーは問い合わせ呼び出し処理の外部へ伝播され、その結果、現在のトランザクションもしくはサブトランザクションはアボートされます。 これは実質的にTclのerrorコマンドと同一です。 FATALはトランザクションをアボートし、現在のセッションを停止させます。 (PL/Tcl関数においてこのエラーレベルを使用すべき理由はおそらく存在しませんが、完全性のために用意されています。) 他のレベルは、異なる重要度のメッセージを生成するだけです。 log_min_messagesclient_min_messages設定パラメータは、特定の重要度のメッセージをクライアントに報告するか、サーバのログに書き出すか、あるいはその両方かを制御します。 詳細については第20章および44.8を参照してください。