<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 41.5\. 在PL/Tcl里訪問數據庫 在 PL/Tcl 過程體里有下面的命令可以用于訪問數據庫: ``spi_exec` ?-count ``_n_`? ?-array `_name_`? `_command_` ?`_loop-body_`? 執行一個以字符串形式給出的 SQL 查詢。查詢中的錯誤會導致拋出一個錯誤。否則, `spi_exec`的返回值是命令處理的行數(選出、插入、更新、刪除), 如果該命令是一個功能性語句則返回零。另外,如果查詢是一條`SELECT`語句, 那么選出的字段值按照下面描述的方法放在 Tcl 變量中。 可選的`-count`值告訴`spi_exec`在該查詢中處理的最大的行數。 其效果和把查詢設置為一個游標,然后說`FETCH` `_n_`是一樣的。 如果查詢是一個`SELECT`語句,那么其結果列的數值將放在用各字段名命名的 Tcl 變量中。 如果給出了`-array`選項,那么字段值將放到這個命名的相關數組中,字段名用做數組索引。 如果查詢是`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 ,那么其目標變量就是"unset"而不會設置上什么東西。 `spi_prepare` `_query_` `_typelist_` 為后面的執行準備并保存一個查詢規劃。保存的規劃的生命期就是當前會話的生命期。 查詢可以使用參數,這些參數是規劃實際執行的時候提供的數值的占位符。在查詢字符串里, 用符號`$1` ... `$``_n_`引用各個參數。 如果查詢使用了參數,那么參數類型名必需以一個 Tcl 列表的形式給出。如果沒有使用參數,那么給 `_typelist_`寫一個空列表。 `spi_prepare`的返回值是一個可以在隨后的`spi_execp` 調用中使用的查詢 ID 。參閱`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` 哪些參數是 NULL 。如果給出,那么它必需和`_value-list_`的長度相同。 如果沒有給出,那么所有參數值都是非 NULL 。 除了查詢及其參數聲明的方式之外,`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 &gt;= \$1 AND num &lt;= \$2" \ [ list int4 int4 ] ] } spi_execp -count 1 $GD(plan) [ list $1 $2 ] return $cnt $$ LANGUAGE pltcl; ``` 需要在給`spi_prepare`的查詢字符串里放反斜杠,以確保`$``_n_` 標記會原樣傳遞給`spi_prepare`,而不是被 Tcl 的變量代換替換掉。 `spi_lastoid` 如果該查詢是單行`INSERT`并且被修改的表包含 OID ,則返回最后的 `spi_exec`或`spi_execp`查詢插入的行的 OID 。如果不是,將得到零。 `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](#calibre_link-1449) 和[client_min_messages](#calibre_link-1448)配置變量控制的。參閱[Chapter 18](#calibre_link-500)獲取更多細節。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看