W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
SPI_execute — 執(zhí)行一個命令
int SPI_execute(const char * command
, bool read_only
, long count
)
SPI_execute
執(zhí)行指定的 SQL 命令以獲得count
行。如果read_only
為true
,該命令必須是只讀的,并且執(zhí)行開銷也會有所降低。
只能從一個已連接的C函數(shù)中調(diào)用這個函數(shù)。
如果count
為零,那么該命令會為其所適用的所有行執(zhí)行。如果count
大于零,那么會檢索不超過count
行,當(dāng)?shù)竭_(dá)該計數(shù)時執(zhí)行會停止,這很像為查詢增加一個LIMIT
子句。例如:
SPI_execute("SELECT * FROM foo", true, 5);
會從表中檢索至多 5 行。注意這樣一個限制只有當(dāng)命令真正返回行時才有效。例如:
SPI_execute("INSERT INTO foo SELECT * FROM bar", false, 5);
插入所有來自于bar
的行,而忽略count
參數(shù)。不過,通過
SPI_execute("INSERT INTO foo SELECT * FROM bar RETURNING *", false, 5);
將插入至多 5 行,因為在第五個RETURNING
結(jié)果行被檢索到后執(zhí)行就會停止。
你可以在一個字符串中傳遞多個命令,SPI_execute
會返回最后一個被執(zhí)行的命令的結(jié)果。 count
限制單獨適用于每一個命令(即便只有最后一個結(jié)果會被實際返回)。該限制 不適用于由規(guī)則產(chǎn)生的任何隱藏命令。
當(dāng)read_only
是false
時, SPI_execute
增加命令計數(shù)器并且在執(zhí)行字符串中每一個命令之前 計算一個新的snapshot。如果當(dāng)前事務(wù)隔離級別是SERIALIZABLE
或
REPEATABLE READ
, 該快照并不會實際改變。但是在READ COMMITTED
模式中,快照更新允許每個命令看到來自其他會話中新近已提交事務(wù) 的結(jié)果。當(dāng)命令正在修改數(shù)據(jù)庫時,這對一致性行為非常重要。
當(dāng)read_only
是true
時, SPI_execute
不更新快照或者命令計數(shù)器,并且它只允許純 SELECT
命令出現(xiàn)在命令字符串中。這些命令被使用之前為周圍查詢 建立的快照來執(zhí)行。這種執(zhí)行模式要比讀/寫模式更快,因為消除了每個命令跟新快照的開銷。
它也允許建立真正stable的函數(shù):因為連續(xù)執(zhí)行將會使用同一個快照,因此結(jié)果不會有改變。
在一個使用 SPI 的單一函數(shù)中混合只讀和讀寫命令通常是不明智的, 這樣可能會導(dǎo)致非常令人困惑的行為,因為只讀查詢將看不到任何 由讀寫查詢完成的數(shù)據(jù)庫更新結(jié)果。
被執(zhí)行的(最后一個)命令的實際行數(shù)使用全局變量SPI_processed
返回。 如果該函數(shù)的返回值是SPI_OK_SELECT
、 SPI_OK_INSERT_RETURNING
、 SPI_OK_DELETE_RETURNING
或者 SPI_OK_UPDATE_RETURNING
,
那么你可以使用全局指針SPITupleTable *SPI_tuptable
來訪問結(jié)果行。 某些工具命令(例如EXPLAIN
)也返回行集合,并且在這些情況中SPI_tuptable
也會包含該結(jié)果。某些工具命令(COPY
、CREATE TABLE AS
)不返回一個行集合,
因此SPI_tuptable
為 NULL,但是它們?nèi)匀粫?code class="varname">SPI_processed中返回被處理的行數(shù)。
結(jié)構(gòu)SPITupleTable
被定義為:
typedef struct SPITupleTable
{
/* Public members */
TupleDesc tupdesc; /* tuple descriptor */
HeapTuple *vals; /* array of tuples */
uint64 numvals; /* number of valid tuples */
/* Private members, not intended for external callers */
uint64 alloced; /* allocated length of vals array */
MemoryContext tuptabcxt; /* memory context of result table */
slist_node next; /* link for internal bookkeeping */
SubTransactionId subid; /* subxact in which tuptable was created */
} SPITupleTable;
SPI 調(diào)用者可以使用字段tupdesc
、vals
和numvals
; 其余字段是內(nèi)部的。 vals
是一個指向行的指針數(shù)組。 行數(shù)由 numvals
給出(由于某些歷史原因,這個計數(shù)也在
SPI_processed
中返回)。 tupdesc
是一個行描述符,您可以將其傳遞給處理行的 SPI 函數(shù)。
SPI_finish
釋放在當(dāng)前的C函數(shù)中已分配的所有SPITupleTable
。 如果你已經(jīng)用完了一個結(jié)果表,你可以通過調(diào)用SPI_freetuptable
提早釋放它。
const char * command
包含要執(zhí)行命令的字符串
bool read_only
對只讀執(zhí)行為true
long count
要返回的最大行數(shù),或者用0
表示沒有限制
如果命令的執(zhí)行成功,那么將會返回下列(非負(fù))值之一:
SPI_OK_SELECT
如果執(zhí)行了一個SELECT
(但不是SELECT INTO
)
SPI_OK_SELINTO
如果執(zhí)行了一個SELECT INTO
SPI_OK_INSERT
如果執(zhí)行了一個INSERT
SPI_OK_DELETE
如果執(zhí)行了一個DELETE
SPI_OK_UPDATE
如果執(zhí)行了一個UPDATE
SPI_OK_INSERT_RETURNING
如果執(zhí)行了一個INSERT RETURNING
SPI_OK_DELETE_RETURNING
如果執(zhí)行了一個DELETE RETURNING
SPI_OK_UPDATE_RETURNING
如果執(zhí)行了一個UPDATE RETURNING
SPI_OK_UTILITY
如果執(zhí)行了一個工具命令(例如CREATE TABLE
)
SPI_OK_REWRITTEN
如果該命令被一個規(guī)則重寫成了另一類命令(例如UPDATE
變成了一個INSERT
)
發(fā)生錯誤時,將會返回下列負(fù)值之一:
SPI_ERROR_ARGUMENT
如果command
為NULL
或者count
小于 0
SPI_ERROR_COPY
如果嘗試COPY TO stdout
或者COPY FROM stdin
SPI_ERROR_TRANSACTION
如果嘗試了一個事務(wù)操縱命令( BEGIN
、 COMMIT
、 ROLLBACK
、 SAVEPOINT
、 PREPARE TRANSACTION
、 COMMIT PREPARED
、
ROLLBACK PREPARED
或者其他變體)
SPI_ERROR_OPUNKNOWN
如果命令類型位置(不應(yīng)該會發(fā)生)
SPI_ERROR_UNCONNECTED
如果從未連接的C函數(shù)中調(diào)用
所有 SPI 查詢執(zhí)行函數(shù)都會設(shè)置SPI_processed
和SPI_tuptable
(只是指針, 而不是結(jié)構(gòu)的內(nèi)容)。如果你需要在以后訪問SPI_execute
或另一個查詢執(zhí)行函數(shù)的結(jié)果表, 請將這兩個全局變量保存到本地的C函數(shù)變量中。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: