SPI_execute

Name

SPI_execute -- 執行一條命令

Synopsis

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

描述

SPI_exec 執行聲明的 SQL 命令獲取 count 行。 如果 read_only 為真,命令必須是只讀的,因此可以略微降低一些執行的開銷。

這個函數只能在已連接的過程中調用。

如果 count 是零,則在命令適合的所有行上執行。 如果 count 大於 0,那麼命令執行的行數將被限制(很像一個 LIMIT 子句)。 比如,

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

將只允許最多 5 行插入資料表中。

您可以在一個字串裡傳遞多個命令。 SPI_execute 返回最後執行的命令的結果。 count 的限制獨立地應用於每一個命令, 但是不會應用於規則生成的隱藏命令。

如果 read_onlyfalseSPI_execute 遞增命令計數器並且在執行字串裡的每個命令之前計算一個新的"快照"。 如果目前交易的隔離級別是SERIALIZABLE,這個快照實際上並不改變, 但是在 READ COMMITTED 模式裡,這個快照更新允許每個命令看到其它會話的交易提交的結果。 這樣實際上是為了修改資料庫的命令有一致的行為。

如果 read_onlytrueSPI_execute 並不更新快照或者命令計數器,並且它指允許簡單的 SELECT 命令出現在命令字串裡。這個命令使用為周圍的查詢建立起來的快照執行。 這個執行模式比讀/寫模式執行得略微塊些,因為它消除了每個命令的一些開銷。 並且它還允許製作真正穩定的函數:因為隨後的執行都將使用同一個快照, 結果裡不會有改變。

通常,在同一個使用 SPI 的函數里混雜只讀和讀寫命令是不明智的; 那樣可能導致非常混亂的行為,因為只讀的查詢不能看到任何讀寫的查詢做的資料庫更新。

(最後)一條命令執行返回的結果的實際行數會放在全局的變量 SPI_processed 裡 (除非函數返回的值是 SPI_OK_UTILITY)。如果函數的返回值是 SPI_OK_SELECT, 那麼您可以使用全局指針 SPITupleTable *SPI_tuptable 訪問結果行。

結構 SPITupleTable 是這樣定義的:

typedef struct
{
    MemoryContext tuptabcxt;    /* 結果資料表的內存環境 */
    uint32      alloced;        /* 分配的 vals 的數目 */
    uint32      free;           /* 空閒的 vals 數目 */
    TupleDesc   tupdesc;        /* 行描述符 */
    HeapTuple  *vals;           /* 資料行 */
} SPITupleTable;

vals 是一個指向資料行的的指針數組。 (有效記錄的數目由 SPI_processed 給出)。 tupdesc 是一個行描述符,您可以傳遞給 SPI 函數處理這些資料行。 tuptabcxtalloced,和 free 是 SPI 的內部字串,並非給 SPI 調用者使用的。

SPI_finish 釋放所有在目前過程中分配的 SPITupleTables。 如果您已經處理完特定的結果資料表,那麼可以更早地釋放它,方法是調用 SPI_freetuptable

參數

const char * command

包含要執行的命令的字串

bool read_only

true 用於只讀的執行

int count

處理或返回的最大行數

返回值

如果命令執行成功,那麼返回下列值之一(非負數):

SPI_OK_SELECT

如果執行了一個 SELECT(但不是 SELECT INTO

SPI_OK_SELINTO

如果執行了一條 SELECT INTO

SPI_OK_DELETE

如果執行了一條 DELETE

SPI_OK_INSERT

如果執行了一條 INSERT

SPI_OK_UPDATE

如果執行了一條 UPDATE

SPI_OK_UTILITY

如果執行了一條工具命令您(比如,CREATE TABLE

發生錯誤時,返回下列負數值之一:

SPI_ERROR_ARGUMENT

如果 commandNULL 或者 count 小於 0

SPI_ERROR_COPY

如果企圖進行 COPY TO stdout 或者 COPY FROM stdin

SPI_ERROR_CURSOR

如果企圖進行 DECLARECLOSE,或者 FETCH

SPI_ERROR_TRANSACTION

如果企圖進行 BEGINCOMMIT,或者 ROLLBACK

SPI_ERROR_OPUNKNOWN

命令類型未知(不應該發生)

SPI_ERROR_UNCONNECTED

如果從一個未連接的過程中調用

注意

函數 SPI_executeSPI_execSPI_execute_planSPI_execp, 和 SPI_prepare 修改 SPI_processedSPI_tuptable (只是一個指針,不是結構的內容)。如果您需要跨越後面的調用訪問 SPI_execute 或者相關函數的結果資料表,那麼需要把這兩個全局倆保存到一個局部過程變量中。