在本節中,我們遵循常用的 Tcl 慣例,使用問號而非方括號來表示語法概要中的可選元素。以下命令可用於從 PL/Tcl 函數的主體存取資料庫
spi_exec
?-count n
? ?-array name
? command
?loop-body
?
執行以字串形式給定的 SQL 命令。命令中的錯誤會引發錯誤。否則,spi_exec
的傳回值是命令處理的列數 (已選取、已插入、已更新或已刪除),如果命令是公用程式陳述式,則傳回零。此外,如果命令是 SELECT
陳述式,則選取欄的值將置於 Tcl 變數中,如下所述。
可選的 -count
值會告知 spi_exec
在擷取 n
列後停止,就像查詢包含 LIMIT
子句一樣。如果 n
為零,則查詢將執行到完成,與省略 -count
時相同。
如果命令是 SELECT
陳述式,則結果欄的值將置於以欄命名的 Tcl 變數中。如果給定了 -array
選項,則欄值會改為儲存到具名關聯陣列的元素中,欄名稱用作陣列索引。此外,結果中的目前列號(從零開始計數)儲存在名為 「.tupno
」的陣列元素中,除非該名稱已用作結果中的欄名稱。
如果命令是 SELECT
陳述式且未給定 loop-body
指令碼,則只有第一列結果儲存到 Tcl 變數或陣列元素中;剩餘的列(如果有的話)將被忽略。如果查詢沒有傳回列,則不會進行儲存。(可以透過檢查 spi_exec
的結果來偵測這種情況。)例如
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
會將 Tcl 變數 $cnt
設定為 pg_proc
系統目錄中的列數。
如果給定了可選的 loop-body
引數,則它是一段 Tcl 指令碼,針對查詢結果中的每一列執行一次。(如果給定的命令不是 SELECT
,則會忽略 loop-body
。)在每次迭代之前,目前列的欄的值會儲存到 Tcl 變數或陣列元素中。例如
spi_exec -array C "SELECT * FROM pg_class" { elog DEBUG "have table $C(relname)" }
將為 pg_class
的每一列列印一條記錄訊息。此功能的工作方式與其他 Tcl 迴圈結構類似;特別是,continue
和 break
在迴圈主體中以通常的方式工作。
如果查詢結果的欄為 null,則該欄的目標變數會「取消設定」,而不是設定。
spi_prepare
query
typelist
準備並儲存查詢計劃以供稍後執行。儲存的計劃將在目前會話的生命週期內保留。
查詢可以使用參數,也就是每次實際執行計劃時要提供的數值的預留位置。在查詢字串中,使用符號 $1
... $
引用參數。如果查詢使用參數,則必須以 Tcl 清單的形式給定參數類型的名稱。(如果未使用任何參數,請編寫一個空清單作為 n
typelist
。)
spi_prepare
的傳回值是一個查詢 ID,用於後續呼叫 spi_execp
。請參閱 spi_execp
以取得範例。
spi_execp
?-count n
? ?-array name
? ?-nulls string
? queryid
?value-list
? ?loop-body
?
執行先前用 spi_prepare
準備好的查詢。queryid
是由 spi_prepare
傳回的 ID。如果查詢引用了參數,則必須提供 value-list
。這是一個 Tcl 清單,包含參數的實際值。清單的長度必須與先前提供給 spi_prepare
的參數類型清單相同。如果查詢沒有參數,則省略 value-list
。
對於 -nulls
的可選值是一個由空格和 'n'
字元組成的字串,告訴 spi_execp
哪些參數是空值。如果給定,它的長度必須與 value-list
完全相同。如果未給定,則所有參數值都不是空值。
除了指定查詢及其參數的方式之外,spi_execp
的工作方式與 spi_exec
完全相同。-count
、-array
和 loop-body
選項是相同的,結果值也是如此。
這是一個使用預先準備計畫的 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;
我們需要在給 spi_prepare
的查詢字串中使用反斜線,以確保 $
標記會原封不動地傳遞給 n
spi_prepare
,而不會被 Tcl 變數替換。
subtransaction
command
包含在 command
中的 Tcl 腳本在 SQL 子交易中執行。如果腳本返回錯誤,則整個子交易會被回滾,然後將錯誤返回到周圍的 Tcl 程式碼。 有關更多詳細資訊和範例,請參閱第 42.9 節。
quote
string
在給定的字串中將所有單引號和反斜線字元加倍。這可以用於安全地引用要插入到提供給 spi_exec
或 spi_prepare
的 SQL 命令中的字串。例如,考慮一個像這樣的 SQL 命令字串
"SELECT '$val' AS ret"
其中 Tcl 變數 val
實際上包含 doesn't
。 這將導致最終的命令字串
SELECT 'doesn't' AS ret
這將在 spi_exec
或 spi_prepare
期間導致解析錯誤。 為了正常工作,提交的命令應包含
SELECT 'doesn''t' AS ret
可以在 PL/Tcl 中使用以下方式形成
"SELECT '[ quote $val ]' AS ret"
spi_execp
的一個優點是您不必像這樣引用參數值,因為這些參數永遠不會被解析為 SQL 命令字串的一部分。
elog
level
msg
發出日誌或錯誤訊息。可能的級別是 DEBUG
、LOG
、INFO
、NOTICE
、WARNING
、ERROR
和 FATAL
。ERROR
引發一個錯誤狀況;如果這沒有被周圍的 Tcl 程式碼捕獲,則該錯誤會傳播到調用的查詢,導致目前的交易或子交易中止。這實際上與 Tcl error
命令相同。FATAL
中止交易並導致目前的會話關閉。(在 PL/Tcl 函數中使用此錯誤級別可能沒有好的理由,但為了完整性而提供它。)其他級別僅產生不同優先順序的消息。是否將特定優先順序的消息報告給客戶端、寫入伺服器日誌,或者兩者都報告,由 log_min_messages 和 client_min_messages 配置變數控制。 有關更多資訊,請參閱第 19 章和第 42.8 節。
如果您在文件中發現任何不正確、與您對特定功能的體驗不符或需要進一步澄清的地方,請使用此表單報告文件問題。