★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

SPI_execute

名前

SPI_execute -- コマンドを実行する

概要

int SPI_execute(const char * command, bool read_only, long count)

説明

SPI_executeは指定したSQLコマンドを、count行分実行します。 read_onlytrueの場合、そのコマンドは読み取りのみでなければなりませんが、多少のオーバーヘッドが削減されます。

この関数は接続済みのプロシージャからのみ呼び出し可能です。

countが0の場合、そのコマンドを、適用される全ての行に対して実行します。 countが0より多ければ、countを超えない数の行が取り出されます。 問い合わせにLIMIT句と追加するの同じように、countに達すれば、実行は止まります。 例えば、

SPI_execute("SELECT * FROM foo", true, 5);

は、テーブルから多くても5行しか取り出しません。 この制限はコマンドが実際に行を返した場合にのみ有効なことに注意して下さい。 例えば

SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);

は、countパラメータを無視して、barからすべての行を挿入します。 しかし、

SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);

は、5番目のRETURNINGの結果行を取り出した後に実行が止まりますので、多くても5行を挿入するだけです。

複数のコマンドを1つの文字列として渡すことができます。 SPI_executeは最後に実行したコマンドの結果を返します。 count制限は(最後の結果が返されただけだとしても)それぞれのコマンドに独立に適用されます。 この制限はルールによって生成される隠れたコマンドには適用されません。

read_onlyfalseの場合、文字列内の各コマンドを実行する前にSPI_executeはコマンドカウンタを増分し、新しいスナップショットを作成します。 このスナップショットは、現在のトランザクション隔離レベルがSERIALIZABLEまたはREPEATABLE READの場合は変更されません。 しかし、READ COMMITTEDモードでは、このスナップショットは更新され、他のセッションで新しくコミットされたトランザクションの結果を各コマンドから参照できます。 これは、そのコマンドがデータベースを変更する場合、一貫性の維持に重要です。

read_onlytrueの場合は、SPI_executeはスナップショットもコマンドカウンタも更新しません。 さらに、普通のSELECTコマンドのみをコマンド文字列内に記述することができます。 このコマンドは、その前後の問い合わせによって事前に確立済みのスナップショットを使用して実行されます。 この実行モードは読み書きモードよりもコマンドごとのオーバーヘッドが省略される分多少高速です。 また、これにより本当に安定(stable)な関数を構築することができます。 つまり、連続した実行は全て同じスナップショットを使用しますので、結果は変わることがないということです。

一般的に、SPIを使用する1つの関数内で読み取りのみコマンドと読み書きコマンドを混在させることは勧めません。 読み取りのみの問い合わせでは、読み書き問い合わせでなされたデータベースの更新結果を参照しないいため、非常に混乱した動作に陥ることがあります。

(最後の)コマンドが実行した実際の行数は、SPI_processedグローバル変数に返されます。 関数の戻り値がSPI_OK_SELECTSPI_OK_INSERT_RETURNINGSPI_OK_DELETE_RETURNING、またはSPI_OK_UPDATE_RETURNINGの場合、SPITupleTable *SPI_tuptableグローバルポインタを使用して、結果の行にアクセスすることができます。 また、一部のユーティリティコマンド(EXPLAINなど)は行セットを返しますが、この場合もSPI_tuptableにはその結果が含まれます。 一部のユーティリティコマンド(COPY, CREATE TABLE AS)は行セットを返しません。 このためSPI_tuptableはNULLですが、SPI_processedの中で処理行数を返します。

SPITupleTable構造体は以下のように定義されています。

typedef struct
{
    MemoryContext tuptabcxt;    /* 結果テーブルのメモリコンテキスト */
    uint32      alloced;        /* 割り当て済みのvalsの数 */
    uint32      free;           /* 解放されたvalsの数 */
    TupleDesc   tupdesc;        /* 行記述子 */
    HeapTuple  *vals;           /* 行 */
} SPITupleTable;

valsが行へのポインタの配列です (有効な項目数はSPI_processedで判明します)。 tupdescは行を扱うSPI関数に渡すことができる行記述子です。 tuptabcxtallocedfreeはSPI呼び出し元での使用を意図していない内部的なフィールドです。

SPI_finishは、現在のプロシージャで割り当てられたSPITupleTableをすべて解放します。 SPI_freetuptableを呼び出して解放する場合、特定の結果テーブルを早めに解放することができます。

引数

const char * command

実行するコマンドを含む文字列。

bool read_only

読み取りのみの実行の場合true

long count

返される行の最大数。無制限なら0。

戻り値

コマンドの実行に成功した場合、以下のいずれかの(非負の)値が返されます。

SPI_OK_SELECT

SELECTSELECT INTOを除く)が実行された場合。

SPI_OK_SELINTO

SELECT INTOが実行された場合。

SPI_OK_INSERT

INSERTが実行された場合。

SPI_OK_DELETE

DELETEが実行された場合。

SPI_OK_UPDATE

UPDATEが実行された場合。

SPI_OK_INSERT_RETURNING

INSERT RETURNINGが実行された場合。

SPI_OK_DELETE_RETURNING

DELETE RETURNINGが実行された場合。

SPI_OK_UPDATE_RETURNING

UPDATE RETURNINGが実行された場合。

SPI_OK_UTILITY

ユーティリティコマンド(CREATE TABLEなど)が実行された場合。

SPI_OK_REWRITTEN

ルールによって(例えば、UPDATEINSERTになったような)あるコマンドが他の種類のコマンドに書き換えられた場合です。

エラーの場合、以下のいずれかの負の値が返されます。

SPI_ERROR_ARGUMENT

commandNULL、あるいはcountが0未満の場合。

SPI_ERROR_COPY

COPY TO stdoutあるいはCOPY FROM stdinが試行された場合。

SPI_ERROR_TRANSACTION

トランザクション操作を行うコマンド(BEGINCOMMITROLLBACKSAVEPOINTPREPARE TRANSACTIONCOMMIT PREPAREDROLLBACK PREPARED、およびこれらの亜種)が試行された場合。

SPI_ERROR_OPUNKNOWN

コマンド種類が不明な場合(起きてはなりません)。

SPI_ERROR_UNCONNECTED

未接続なプロシージャから呼び出された場合。

注意

SPI問い合わせ実行関数はすべてSPI_processedSPI_tuptableの両方を変更します(ポインタのみで、構造体の内容は変更しません)。 SPI_execや他の問い合わせ実行関数の結果テーブルを後の呼び出しでまたがってアクセスしたいのであれば、これら2つのグローバル変数を局所的なプロシージャ変数に保存してください。