<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # 31.3\. 命令執行函數 一旦與數據庫服務器的連接成功建立,便可以使用這里描述的函數執行SQL查詢和命令。 ## 31.3.1\. 主函數 `PQexec` 給服務器提交一條命令并且等待結果。 ``` PGresult *PQexec(PGconn *conn, const char *command); ``` 返回一個`PGresult`指針或者也可能是一個空指針。 通常返回一個非空指針,除非耗盡內存或發生了像不能把命令發送到服務器這樣的嚴重錯誤。 應該調用`PQresultStatus`函數來檢查任何錯誤的返回值 (包括空指針的值,在這種情況下它將返回`PGRES_FATAL_ERROR`)。 使用`PQerrorMessage`獲取有關錯誤的更多信息。 命令字符串可以包括多個SQL命令(用分號分隔)。在一個`PQexec` 調用中發送的多個查詢是在一個事務里處理的,除非在查詢字符串里有明確的 `BEGIN`/`COMMIT`命令把整個字符串分隔成多個事務。 請注意,返回的`PGresult`結構只描述字符串里執行的最后一條命令的結果。 如果有一個命令失敗,那么字符串處理的過程就會停止,并且返回的`PGresult` 會描述錯誤條件。 `PQexecParams` 向服務器提交一條命令并且等待結果,還有獨立于SQL命令文本傳遞參數的能力。 ``` PGresult *PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat); ``` `PQexecParams`類似`PQexec`,但是提供了額外的功能: 參數值可以獨立于命令字符串進行聲明,并且可以要求查詢結果的格式是文本或二進制的。 `PQexecParams`只是在協議3.0及以后的版本中支持;在使用協議2.0的時候會失敗。 函數的參數是: `conn` 連接對象通過它發送命令。 `command` 要執行的SQL命令字符串。如果使用參數,它們在命令字符串中被叫做`$1`、 `$2`等等。 `nParams` 提供的參數數目;它是`paramTypes[]`、`paramValues[]`、 `paramLengths[]`和`paramFormats[]`數組的長度。 (當`nParams`是0時,數組指針可以是`NULL`。) `paramTypes[]` 通過OID,將聲明數據類型指定到參數標記。如果`paramTypes` 是`NULL`,或數組中任何的特定參數是0,服務器為參數標記推斷數據類型, 采用的方式與一個未定義類型的文本字符串相同。 `paramValues[]` 聲明參數的實際值。在這個數組中的一個空指針表示相應的參數是空; 否則指針指向一個以零結尾的文本字符串(文本格式)或者服務器希望的格式的二進制數據 (二進制格式)。 `paramLengths[]` 為二進制格式的參數聲明實際數據長度。該設置忽略空參數或文本格式的參數。 如果沒有二進制參數,那么數組指針可以為空。 `paramFormats[]` 聲明參數為文本(為相應參數在數組條目中放置一個0)還是二進制格式 (為相應參數在數組條目中放置一個1)。如果數組指針是空,那么所有參數被看做是文本字符串。 以二進制格式傳遞的值需要能夠被后臺識別的內部表示。例如,整數必須以網絡字節順序來傳遞。 傳遞`numeric`值需要服務器存儲格式的識別,如在 `src/backend/utils/adt/numeric.c::numeric_send()`和 `src/backend/utils/adt/numeric.c::numeric_recv()`中那樣。 `resultFormat` 聲明0用于以文本格式獲得結果,或1用于以二進制格式獲得結果。 (目前沒有規定以不同的格式來獲取不同的結果列,即使底層協議中可能實現。) `PQexecParams`相比`PQexec`的主要優勢是參數值可以從命令字符串中分離出來, 因此避免了繁瑣和容易出錯的引用和逃逸的需要。 和`PQexec`不同的是,`PQexecParams`在一個給出的字符串里最多允許一個SQL命令。 (里面可以有分號,但是不得超過一個非空的命令。)這是下層協議的一個限制, 但是也有些好處,比如作為對SQL注入攻擊的額外防御。 > **Tip:** 通過OID聲明參數類型是非常繁瑣的,尤其是你不希望在你的程序里寫死特定的OID值的時候。 不過,你可以避免這么做,即使在服務器自己無法判斷參數類型, 或者是選擇了一種與你預期不同的參數類型的時候也一樣。在SQL命令文本里, 給參數符號附加一個明確的類型轉換,顯示你準備發送的數據類型。比如: > > ``` > SELECT * FROM mytable WHERE x = $1::bigint; > ``` > > 這樣強制參數`$1`當作`bigint`看待,即使缺省情況下它會被賦予和 `x`一樣的類型。在以二進制格式發送參數值的時候, 我們強烈建議通過這種方法或者是聲明數字類型OID的方法強制類型判斷, 因為二進制格式比文本格式少一些冗余,因此服務器就會少一些機會捕捉類型的錯誤匹配。 `PQprepare` 用給定的參數提交請求,創建一個預備語句,然后等待結束。 ``` PGresult *PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes); ``` `PQprepare`創建一個為后面`PQexecPrepared`執行用的預備語句。 這個特性允許那些重復使用的語句只分析和規劃一次,而不是每次執行都分析規劃。 只是在協議3.0和以后的連接里支持`PQprepare`;在使用2.0協議的時候,它會失敗。 這個函數從`query`字串里創建一個叫`stmtName`的預備語句, `query`必須只包含一個 SQL 命令。`stmtName`可以是`""`, 這樣就創建一個無名的語句,這種情況下,任何前面存在的無名語句都會自動被代替; 否則,如果語句名已經在當前會話里定義,那就是一個錯誤。如果使用了參數, 那么在查詢里它們引用成`$1`,`$2`等等。`nParams` 是參數的個數,參數的類型在數組`paramTypes[]`里事先聲明好了。 (如果`nParams`是零,那么這個數組指針可以是`NULL`。) `paramTypes[]`用 OID 的方式聲明與參數符號關聯的數據類型。 如果`paramTypes`為`NULL`,或者數組中某個特定元素是零, 那么服務器將用處理無類型文本同樣的方法給這個參數符號賦予數據類型。還有, 查詢可以使用比`nParams`數值更大的參數符號編號; 也為這些符號推斷數據類型。(參閱`PQdescribePrepared` 作為一個找出推斷的什么類型的手段。) 和`PQexec`相似,結果通常是一個`PGresult`對象, 其內容表明服務器端是成功還是失敗。空的結果表示內存耗盡或者完全不能發送命令。 使用`PQerrorMessage`獲取有關這類錯誤的更多信息。 用于`PQexecPrepared`的預備語句也可以通過執行SQL [PREPARE](#calibre_link-625)語句來創建。 還有,盡管沒有libpq函數可以刪除一個預備語句, SQL [DEALLOCATE](#calibre_link-479)語句卻可以刪除。 `PQexecPrepared` 發送一個請求,執行一個帶有給出參數的預備語句,并且等待結果。 ``` PGresult *PQexecPrepared(PGconn *conn, const char *stmtName, int nParams, const char * const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat); ``` `PQexecPrepared`和`PQexecParams`類似, 但是要執行的命令是通過命名一個前面準備好的語句聲明的,而不是給出一個查詢字串。 這個特性允許那些要重復使用的命令只進行一次分析和規劃,而不是每次執行都來一遍。 這個語句必須在當前會話的前面已經準備好。`PQexecPrepared` 只在協議 3.0 和以后的版本里支持;在使用 2.0 版本的協議的時候,它們會失敗。 參數和`PQexecParams`一樣,只是給出的是一個預備語句的名字,而不是一個查詢字串, 并且沒有`paramTypes[]`參數(沒必要,因為預備語句的參數類型是在創建的時候確定的)。 `PQdescribePrepared` 提交請求以獲取有關指定的預備語句的信息,并等待完成。 ``` PGresult *PQdescribePrepared(PGconn *conn, const char *stmtName); ``` `PQdescribePrepared`允許應用程序獲取有關先前準備的語句的信息。 `PQdescribePrepared`只在協議 3.0 和以后的版本里支持; 在使用 2.0 版本的協議的時候,它們會失敗。 `stmtName`可以是`""`或`NULL`以指向未命名聲明, 要么必須與現有的預備語句同名。成功時,會返回一個帶有`PGRES_COMMAND_OK` 的`PGresult`。可以在這個`PGresult`中使用 `PQnparams`和`PQparamtype` 函數以獲得預備語句的參數信息,同時`PQnfields`, `PQfname`,`PQftype`等函數提供聲明的結果列(如果有)的信息。 `PQdescribePortal` 提交請求以獲取有關指定的端口的信息,并等待完成。 ``` PGresult *PQdescribePortal(PGconn *conn, const char *portalName); ``` `PQdescribePortal`允許應用程序獲得關于之前創建的端口的信息。 (libpq不提供與端口的直接連接,但可以使用這個函數來檢查 `DECLARE CURSOR`命令創建的游標的屬性)。`PQdescribePortal` 只支持3.0及其之后的連接協議;當使用協議2.0時會失敗。 `portalName`可以是`""`或`NULL`以指向未命名聲明, 要么必須與現有的預備語句同名。成功時,會返回一個帶有`PGRES_COMMAND_OK` 的`PGresult`。可以在`PGresult`中使用 `PQnfields`,`PQfname`, `PQftype`等函數獲取端口的結果列(如果有)的信息。 `PGresult` 結構封裝了服務器返回的結果。libpq應該小心維護 `PGresult`的抽象。使用下面的訪問函數獲取 `PGresult`的內容。避免直接引用`PGresult` 里面的字段,因為它們在未來版本里可能會被修改。 `PQresultStatus` 返回命令的結果狀態。 ``` ExecStatusType PQresultStatus(const PGresult *res); ``` `PQresultStatus`可以返回下面數值之一: `PGRES_EMPTY_QUERY` 發送給服務器的字串是空的。 `PGRES_COMMAND_OK` 成功完成一個不返回數據的命令。 `PGRES_TUPLES_OK` 成功執行一個返回數據的查詢(比如`SELECT`或者`SHOW`)。 `PGRES_COPY_OUT` (從服務器)Copy Out (拷貝出)數據傳輸開始。 `PGRES_COPY_IN` Copy In(拷貝入)(到服務器)數據傳輸開始。 `PGRES_BAD_RESPONSE` 服務器的響應無法理解。 `PGRES_NONFATAL_ERROR` 發生了一個非致命錯誤(通知或者警告)。 `PGRES_FATAL_ERROR` 發生了一個致命錯誤。 `PGRES_COPY_BOTH` 拷貝入/出(到和從服務器)數據傳輸開始。這個特性當前只用于流復制, 所以這個狀態不會在普通應用中發生。 `PGRES_SINGLE_TUPLE` `PGresult`包含一個來自當前命令的結果元組。 這個狀態只在查詢選擇了單行模式時發生(參閱[Section 31.5](#calibre_link-626))。 如果結果狀態是`PGRES_TUPLES_OK`或`PGRES_SINGLE_TUPLE`, 那么可以用下面的函數從查詢的返回中抽取元組信息。注意一個碰巧檢索了零條元組的 `SELECT`仍然顯示`PGRES_TUPLES_OK`。 `PGRES_COMMAND_OK`用于不返回元組的命令(沒有`RETURNING` 子句的`INSERT`,`UPDATE`等)。 返回`PGRES_EMPTY_QUERY`的響應通常意味著暴露了客戶端軟件里面的臭蟲。 狀態為`PGRES_NONFATAL_ERROR`的結果永遠不會直接由`PQexec` 或者其它查詢執行函數返回;這類的結果會被傳遞給通知處理器 (參閱[Section 31.12](#calibre_link-627))。 `PQresStatus` 把`PQresultStatus`返回的枚舉類型轉換成一個描述狀態碼的字符串常量。 調用者不應該釋放結果。 ``` char *PQresStatus(ExecStatusType status); ``` `PQresultErrorMessage` 返回與查詢關聯的錯誤信息,或在沒有錯誤時返回一個空字符串。 ``` char *PQresultErrorMessage(const PGresult *res); ``` 如果有錯誤,那么返回的字串將包括一個結尾的新行。調用者不應該直接釋放結果。 在相關的`PGresult`句柄傳遞給`PQclear`之后,它會自動釋放。 緊跟在一個`PQexec`或`PQgetResult`調用后面, `PQerrorMessage`(對連接)將返回與`PQresultErrorMessage` (對結果)一樣的字符串。不過,一個`PGresult`將保有其錯誤信息直到被刪除, 而連接的錯誤信息將在后續的操作完成時被改變。當你想知道與某個`PGresult` 相關聯的狀態時用`PQresultErrorMessage`; 當你想知道與連接的最近一個操作相關聯的狀態時用`PQerrorMessage`。 `PQresultErrorField` 返回一個獨立的錯誤報告字段。 ``` char *PQresultErrorField(const PGresult *res, int fieldcode); ``` `fieldcode`是一個錯誤字段標識符;參閱下面列出的符號。 如果`PGresult`不是錯誤或者警告結果或者不包括指定的字段, 那么返回`NULL`。字段值通常將不包括結尾的新行。調用者不應該直接釋放結果。 在相關聯的`PGresult`句柄傳遞給`PQclear`之后,它將被自動釋放。 下列代碼是可用的: `PG_DIAG_SEVERITY` 嚴重程度,這個字段的內容是`ERROR`,`FATAL`或者`PANIC` (在錯誤信息里),或者`WARNING`,`NOTICE`,`DEBUG`, `INFO`或`LOG`(在注意信息里),或者是這些東西的一個本地化翻譯。總是出現。 `PG_DIAG_SQLSTATE` 這個錯誤的SQLSTATE代碼。SQLSTATE代碼表示所發生的錯誤的類型; 可以由前端應用用于對特定的數據庫錯誤執行特定的操作(比如錯誤處理)。 可能的SQLSTATE代碼的列表,請查看[Appendix A](#calibre_link-120)。 這個字段是不能區域化的,并且總是出現。 `PG_DIAG_MESSAGE_PRIMARY` 主要的人類可讀錯誤的信息(通常一行)。總是出現。 `PG_DIAG_MESSAGE_DETAIL` 細節:一個可選的從屬錯誤信息,里面有更多有關該問題的細節。可能有多行。 `PG_DIAG_MESSAGE_HINT` 提示:一個可選的有關如何處理該問題的建議。它和細節的區別是它提供了建議 (可能不太合適)而不光是事實。可能有好幾行。 `PG_DIAG_STATEMENT_POSITION` 一個包含十進制整數的字串,表明錯誤游標的位置,作為一個索引指向最初的語句字符串。 第一個字符的索引是 1,并且這個位置是用字符計,而不是用字節計。 `PG_DIAG_INTERNAL_POSITION` 這個和`PG_DIAG_STATEMENT_POSITION`字段定義是一樣的, 區別是它在游標位置指向內部生成的命令時使用,而不是客戶端提交的命令。如果出現了這個字段, 那么`PG_DIAG_INTERNAL_QUERY`字段也總是出現。 `PG_DIAG_INTERNAL_QUERY` 一個失敗的內部生成的命令的文本。比如,這個可能是一個 PL/pgSQL 函數發出的 SQL 查詢。 `PG_DIAG_CONTEXT` 一個指示器,表明錯誤發生的環境。目前這個包括活躍的過程語言函數和內部生成的查詢的調用堆棧跟蹤。 跟蹤是每行一條,最近的在上面。 `PG_DIAG_SCHEMA_NAME` 如果錯誤與特定的數據庫對象相關,那么是包含該對象的模式名(如果有)。 `PG_DIAG_TABLE_NAME` 如果錯誤與特定的表相關,那么是該表的名字。(參考模式名字段獲取表的模式的名字。) `PG_DIAG_COLUMN_NAME` 如果錯誤與特定的表字段相關,那么是該字段的名字。(參考模式和表名字段識別該表。) `PG_DIAG_DATATYPE_NAME` 如果錯誤與特定的數據類型相關,那么是該數據類型的名字。(參考模式名字段獲取數據類型的模式的名字。) `PG_DIAG_CONSTRAINT_NAME` 如果錯誤與特定的約束相關,那么是該約束的名字。參考上面列出的字段獲取相關的表或域。 (為了這個目的,索引被看做是約束,即使它們是用約束語法創建的。) `PG_DIAG_SOURCE_FILE` 報告錯誤的源代碼所在的文件名。 `PG_DIAG_SOURCE_LINE` 報告錯誤的源代碼所在的行號。 `PG_DIAG_SOURCE_FUNCTION` 報告錯誤的源代碼函數的名字。 > **Note:** 只為有限的錯誤類型提供模式名、表名、字段名、數據類型名和約束名字段; 參閱[Appendix A](#calibre_link-120)。不要假設這些字段的出現會保證其他字段的出現。 核心錯誤來源觀察以上提到的相互關系,但是用戶定義的函數可以以其他方式使用這些字段。 同樣的,不要假設這些字段表示當前數據庫中的同時期對象。 按照自身的要求格式化顯示信息是客戶端的責任;特別是根據需要對長行進行折行。 在錯誤信息字段里出現的新行字符應該當作分段符號,而不是換行。 libpq生成的錯誤將會有嚴重性和主信息,但是通常沒有其它字段。 3.0 協議之前返回的錯誤將包含嚴重性和主信息,有時候還有詳細信息,但是沒有其它字段。 請注意這些錯誤字段只能從`PGresult`對象里獲得, 而不是`PGconn`對象;沒有`PQerrorField`函數。 `PQclear` 釋放與`PGresult`相關聯的存儲空間。 任何不再需要的查詢結果都應該用`PQclear`釋放掉。 ``` void PQclear(PGresult *res); ``` 只要你需要,你可以保留`PGresult`對象任意長的時間; 當你提交新的查詢時它并不消失,甚至你斷開連接后也是這樣。要刪除它, 你必須調用`PQclear`。不這么做將導致你應用中的內存泄漏。 ## 31.3.2\. 檢索查詢結果信息 這些函數用于從一個代表著成功查詢結果(也就是說,狀態為`PGRES_TUPLES_OK`或 `PGRES_SINGLE_TUPLE`的查詢)的`PGresult`對象中抽取信息。 它們也可以用于從一個成功描述操作中抽取信息: 一個描述的結果和實際查詢的執行將要提供的結果有所有相同的字段信息,但是它有零行。 對于其它狀態值的對象,他們的行為會好像他們有零行和零列一樣。 `PQntuples` 返回查詢結果里的行(元組)個數。因為它返回一個整數的結果,在32位操作系統上大型結果集可能溢出返回值。 ``` int PQntuples(const PGresult *res); ``` `PQnfields` 返回查詢結果里數據行的列(字段)的個數。 ``` int PQnfields(const PGresult *res); ``` `PQfname` 返回與給出的字段編號相關聯的字段名。字段編號從 0 開始。調用者不應該直接釋放結果。 在相關聯的`PGresult`句柄傳遞給`PQclear`之后,結果會被自動釋放。 ``` char *PQfname(const PGresult *res, int column_number); ``` 如果字段編號超出范圍,那么返回`NULL`。 `PQfnumber` 返回與給出的字段名相關的字段編號。 ``` int PQfnumber(const PGresult *res, const char *column_name); ``` 如果給出的名字不匹配任何字段,返回-1。 給出的名字是當作 SQL 命令里的一個標識符看待的,也就是說,如果沒有加雙引號, 那么會轉換為小寫。比如,如果我們有一個從 SQL 命令里生成的查詢結果: ``` SELECT 1 AS FOO, 2 AS "BAR"; ``` 那么我們會有下面的結果: ``` PQfname(res, 0) _foo_ PQfname(res, 1) _BAR_ PQfnumber(res, "FOO") _0_ PQfnumber(res, "foo") _0_ PQfnumber(res, "BAR") _-1_ PQfnumber(res, "\"BAR\"") _1_ ``` `PQftable` 返回我們抓取的字段所在的表的 OID。字段編號從 0 開始。 ``` Oid PQftable(const PGresult *res, int column_number); ``` 如果字段編號超出了范圍,或者聲明的字段不是一個指向某個表的字段的簡單引用, 或者使用了 3.0 版本之前的協議,那么就會返回`InvalidOid`。 你可以查詢系統表`pg_class`來判斷究竟引用了哪個表。 在你包含libpq頭文件的時候,就會定義類型`Oid` 和常量`InvalidOid`。他們都是相同的整數類型。 `PQftablecol` 返回組成聲明的查詢結果字段的字段號(在它的表內部)。查詢結果字段編號從 0 開始, 但是表字段編號不會是 0。 ``` int PQftablecol(const PGresult *res, int column_number); ``` 如果字段編號超出范圍,或者聲明的字段并不是一個表字段的簡單引用, 或者使用的是 3.0 之前的協議,那么返回零。 `PQfformat` 返回說明給出字段的格式的格式代碼。字段編號從 0 開始。 ``` int PQfformat(const PGresult *res, int column_number); ``` 格式碼為 0 表示文本數據,而格式碼是一表示二進制數據。(其它編碼保留給將來定義。) `PQftype` 返回與給定字段編號關聯的數據類型。返回的整數是一個該類型的內部 OID 號。字段編號從0 開始。 ``` Oid PQftype(const PGresult *res, int column_number); ``` 你可以查詢系統表`pg_type`以獲取各種數據類型的名稱和屬性。 內建的數據類型的OID在源碼樹的 `src/include/catalog/pg_type.h`文件里定義。 `PQfmod` 返回與給定字段編號相關聯的字段的類型修飾符。字段編號從 0 開始。 ``` int PQfmod(const PGresult *res, int column_number); ``` 類型修飾符的值是類型相關的;他們通常包括精度或者尺寸限制。 數值 -1 用于表示"沒有可用信息"。大多數數據類型不用修飾詞,這種情況下該值總是-1。 `PQfsize` 返回與給定字段編號關聯的字段以字節計的大小。字段編號從0 開始。 ``` int PQfsize(const PGresult *res, int column_number); ``` `PQfsize`返回在數據庫行里面給該數據字段分配的空間, 換句話說就是該數據類型在服務器的內部表現形式的大小(尺寸)。(因此, 這個對客戶端沒有什么用。) 負值表示該數據類型是可變長度。 `PQbinaryTuples` 如果`PGresult`包含二進制數據時返回 1,如果包含文本數據返回 0。 ``` int PQbinaryTuples(const PGresult *res); ``` 這個函數已經廢棄了(除了還用于與`COPY`連接之外), 因為我們可能在一個`PGresult`的某些字段里包含文本數據, 而另外一些字段包含二進制數據。更好的是使用`PQfformat`。 `PQbinaryTuples`只有在結果中的所有字段都是二進制(格式 1)的時候才返回 1。 `PQgetvalue` 返回一個`PGresult`里面一行的單獨的一個字段的值。 行和字段編號從 0 開始。調用者不應該直接釋放結果。在把`PGresult` 句柄傳遞給`PQclear`之后,結果會被自動釋放。 ``` char *PQgetvalue(const PGresult *res, int row_number, int column_number); ``` 對于文本格式的數據,`PQgetvalue`返回的值是一個表示字段值的空(NULL) 結尾的字符串。對于二進制格式,返回的值就是由該數據類型的`typsend` 和`typreceive`決定的二進制表現形式。(在這種情況下, 數值實際上也跟著一個字節零,但是通常這個字節沒什么用處,因為數值本身很可能包含內嵌的空。) 如果字段值是空,則返回一個空字串。參閱`PQgetisnull`來區別空值和空字串值。 `PQgetvalue`返回的指針指向一個本身是`PGresult` 結構的一部分的存儲區域。我們不能更改它,并且如果我們要在`PGresult` 結構的生存期后還要使用它的話,我們必須明確地把該數值拷貝到其他存儲器中。 `PQgetisnull` 測試一個字段是否為空(NULL)。行和字段編號從 0 開始。 ``` int PQgetisnull(const PGresult *res, int row_number, int column_number); ``` 如果該域包含 NULL,函數返回 1,如果包含非空(non-null )值,返回 0。 (注意,對一個 NULL 字段,`PQgetvalue`將返回一個空字符串,不是一個空指針。) `PQgetlength` 返回以字節計的字段的長度。行和字段編號從 0 開始。 ``` int PQgetlength(const PGresult *res, int row_number, int column_number); ``` 這是特定數值的實際數據長度,也就是說,`PQgetvalue`指向的對象的大小。 對于文本數據格式,它和`strlen()`相同。對于二進制格式,這是基本信息。 請注意我們_不_應該依靠`PQfsize` 獲取實際數據長度。 `PQnparams` 返回一個預備語句中的參數的數目。 ``` int PQnparams(const PGresult *res); ``` 只有在檢查`PQdescribePrepared`的結果時,這個函數是有用的。 對于其他類型的查詢將返回零。 `PQparamtype` 返回指示語句中的參數的數據類型。參數編號從0開始。 ``` Oid PQparamtype(const PGresult *res, int param_number); ``` 只有在檢查`PQdescribePrepared`的結果時,這個函數是有用的。 對于其他類型的查詢將返回零。 `PQprint` 向指定的輸出流打印所有的行和(可選的)字段名稱。 ``` void PQprint(FILE *fout, /* 輸出流 */ const PGresult *res, const PQprintOpt *po); typedef struct { pqbool header; /* 打印輸出字段頭和行計數 */ pqbool align; /* 填充對齊字段 */ pqbool standard; /* 舊的格式 */ pqbool html3; /* 輸出HTML表 */ pqbool expanded; /* 擴展表 */ pqbool pager; /* 必要時在輸出中使用分頁器 */ char *fieldSep; /* 字段分隔符 */ char *tableOpt; /* HTML表格元素的屬性 */ char *caption; /* HTML表標題 */ char **fieldName; /* 替換字段名組成的空結尾的數組 */ } PQprintOpt; ``` 這個函數以前被psql用于打印查詢結果,但是現在已經不用這個函數了。 請注意它假設所有的數據都是文本格式。 ## 31.3.3\. 檢索其它命令的結果信息 這些函數用于從`PGresult`對象里檢索其他信息。 `PQcmdStatus` 返回產生`PGresult`的 SQL 命令的命令狀態標簽。 ``` char *PQcmdStatus(PGresult *res); ``` 通常這只是命令的名字,但是它可能包括額外的數據,比如處理過的行數。調用者不應該直接釋放結果。 結果會在把`PGresult`句柄傳遞給`PQclear`的時候釋放。 `PQcmdTuples` 返回被 SQL 命令影響的行的數量。 ``` char *PQcmdTuples(PGresult *res); ``` 這個函數返回一個字符串,包含`PGresult`產生的SQL語句影響的行數。 這個函數只能用于下列的執行:`SELECT`,`CREATE TABLE AS`,`INSERT`, `UPDATE`,`DELETE`,`MOVE`,`FETCH`,或者 `COPY`語句,或者是一個包含`INSERT`,`UPDATE`或`DELETE` 語句的預備查詢的`EXECUTE`。如果生成這個`PGresult`的命令是其他的東西, 那么`PQcmdTuples`返回一個空字串。調用者不應該直接釋放返回的數值。 在相關聯的`PGresult`被傳遞給`PQclear`之后,它會被自動釋放。 `PQoidValue` 返回插入的行的OID, 如果SQL命令是`INSERT`,插入了正好一行到有OID的表格, 或者是一個包含合適`INSERT`語句的預備查詢`EXECUTE`的時候。 否則,函數返回`InvalidOid`。如果受`INSERT` 影響的表不包含 OID,也返回`InvalidOid`。 ``` Oid PQoidValue(const PGresult *res); ``` `PQoidStatus` 為了支持`PQoidValue`,這個函數已經廢棄了,并且不是線程安全的。 它返回插入行的帶有OID的字符串,而`PQoidValue`返回OID值。 ``` char *PQoidStatus(const PGresult *res); ``` ## 31.3.4\. 逃逸包含在SQL命令中的字符串 `PQescapeLiteral` ``` char *PQescapeLiteral(PGconn *conn, const char *str, size_t length); ``` `PQescapeLiteral`為在 SQL 命令中使用字串而對之進行逃逸處理。 在我們向 SQL 命令里把數據值當作文本常量插入的時候很有用。有些字符 (比如單引號和反斜杠)必須被逃逸,以避免他們被 SQL 分析器作為特殊字符解析。 `PQescapeLiteral`執行這個操作。 `PQescapeLiteral`返回一個內存中分配有`malloc()`的 `str`參數的逃逸版本。當結果不再需要時,需要通過`PQfreemem()` 來釋放這塊內存。不需要一個0字節結束,并且不應以`length`計數。 (如果在處理`length`字節之前出現0字節的結束,`PQescapeLiteral` 在此處結束;這個行為有點像`strncpy`)。返回的字符串中所有特殊字符都替換掉了, 因此可以很好的被PostgreSQL字符串文本解析器處理,同樣, 允許增加一個0字節結尾。必須在PostgreSQL 字符串文本兩邊的單引號包含在結果字符串中。 一旦錯誤,`PQescapeLiteral`返回`NULL`并在`conn`對象中存儲合適的信息。 > **Tip:** 處理從不可信來源收到的字符串時必須進行合適的逃逸,否則存在一定的安全風險: 容易受到"SQL 注入"攻擊,數據庫中會被寫入未知的SQL命令。 需要注意的是,當一個數據以`PQexecParams`或它的兄弟格式, 作為一個單獨的參數傳遞時,做逃逸是不必要,也是不正確的。 `PQescapeIdentifier` ``` char *PQescapeIdentifier(PGconn *conn, const char *str, size_t length); ``` `PQescapeIdentifier`逃逸一個字符串作為一個SQL標識符使用, 如一個表,列,或函數名。當一個用戶自定義標識符需要包含特殊的字符, 否則將不能被SQL解析器解析為標識符的一部分時,或者當標識符需要包含大寫字母, 且這種情況必須保留時,這樣做是很有用的。 `PQescapeIdentifier`返回`str`參數逃逸為一個內存中分配有 `malloc()`的SQL標識符的版本。當結果不再需要時,這塊內存必須使用 `PQfreemem()`來釋放。不需要一個0字節結束,并且不應以`length`計數。 (如果在處理`length`字節之前出現0字節的結束,`PQescapeIdentifier` 在此處結束;這個行為比較像`strncpy`)。返回的字符串中所有特殊字符都替換掉了, 因此可以很好的作為SQL標識符被處理。也可以添加一個結尾的0字節。返回字符串也是被雙引號環繞。 出錯時,`PQescapeIdentifier`返回`NULL`,并且在`conn`對象中存貯合適的信息。 > **Tip:** 由于帶有字符串常量,為阻止SQL注入攻擊,當從一個不可信任資源獲得時,SQL標識符必須逃逸。 `PQescapeStringConn` ``` size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error); ``` `PQescapeStringConn`逃逸字符串常量,比較像`PQescapeLiteral`。 不同于`PQescapeLiteral`,請求應該提供一個適當大小的緩沖區。更重要的是, `PQescapeStringConn`不會生成一個必須在PostgreSQL 字符串常量兩端的單引號;SQL命令中應該提供,這樣結果中會被插入。`from` 參數指向字符串的第一個字符(用以逃逸),`length`參數指出了在這個字符串中的字節數。 不需要一個0字節結束,并且不應以`length`計數。 (如果在處理`length`字節之前出現0字節的結束,`PQescapeStringConn` 在此處結束;這個行為比較像`strncpy`)。`to`應該指向一個包含至少多于兩倍 `length`大小的緩沖區,要么就不會定義該行為。如果`to`和`from` 字符串交疊,那么也不會定義該行為。 `error`參數非`NULL`,那么在成功的時候`*error`會被設置為零, 失敗的時候設置為非0。目前唯一可能的錯誤條件涉及在源字符串中無效的多字節編碼。 輸出字符串同樣產生錯誤,但服務器可以視其為異常以拒絕。一旦發生錯誤, 一條合適的信息會存儲在`conn`對象中,無論`error`是否為`NULL`。 `PQescapeStringConn`返回寫到`to`的字節數,不包含0字節終止。 `PQescapeString` `PQescapeString`是一個老的,已經被`PQescapeStringConn`棄用了的版本。 ``` size_t PQescapeString (char *to, const char *from, size_t length); ``` 與`PQescapeStringConn`唯一的不同是,`PQescapeString` 不使用`PGconn`或`error`參數。因此,不能夠根據連接屬性 (如字符編碼)來調整其行為,因此_可能會給出錯誤的結果_,同樣,不會報告錯誤條件。 `PQescapeString`可以在客戶端編程(一次只有一個PostgreSQL連接) 中安全的使用。在這種情況下,它可以找到"在屏幕背后"想要知道的。在其他情況下, 這是一個安全隱患,使用`PQescapeStringConn`時應該避免。 `PQescapeByteaConn` 逃逸那些在 SQL 命令中使用的用`bytea`表示的二進制數據。 和`PQescapeStringConn`一樣,這個函數只有在直接向 SQL 字串插入數據的時候使用。 ``` unsigned char *PQescapeByteaConn(PGconn *conn, const unsigned char *from, size_t from_length, size_t *to_length); ``` 在SQL語句中用做`bytea`字串文本的一部分的時候, 有些字節值必需逃逸。`PQescapeByteaConn`逃逸字節使用十六進制編碼或反斜杠逃逸。 參閱[Section 8.4](#calibre_link-628)獲取更多信息。 `from`參數指向需要逃逸的字串的第一個字節,`from_length` 參數反映在這個二進制字串(結尾的字節零既不必要也不計算在內)里字節的個數。 `to_length`參數指向一個變量,它保存逃逸后字符串長度的結果。 結果字串長度包括結果結尾的零字節。 `PQescapeByteaConn`在內存中返回一個`from` 參數的二進制字串的逃逸后的版本,這片內存是用`malloc()`分配的 在不再需要結果的時候,必須用`PQfreemem()`釋放內存。 返回的字串已經把所有特殊的字符替換掉了,這樣他們就可以由PostgreSQL 的字串文本分析器以及`bytea`的輸入函數正確地處理。同時還追加了一個結尾的字節零。 那些必需包圍在PostgreSQL字串文本周圍的單引號并非結果字串的一部分。 當出錯時,返回一個空指針,一個合適的錯誤信息會被儲存在`conn`對象中, 當前唯一可能的錯誤是結果字符串的內存不足。 `PQescapeBytea` `PQescapeBytea`是`PQescapeByteaConn`的一個舊的,過時的版本。 ``` unsigned char *PQescapeBytea(const unsigned char *from, size_t from_length, size_t *to_length); ``` 與`PQescapeByteaConn`唯一的不同之處在于,`PQescapeByteaConn` 不使用`PGconn`參數,因此,`PQescapeBytea`可以在客戶端編程 (一次只有一個PostgreSQL連接)中安全的使用。在這種情況下, 它可以找到"在屏幕背后"想要知道的。如果在編程中使用多個數據庫連接 (在這種情況下使用`PQescapeByteaConn`),那么_可能會給出錯誤結果_。 `PQunescapeBytea` 把一個二進制數據的字符串表現形式轉換成二進制數據— `PQescapeBytea`的反作用。在以文本格式抽取`bytea` 數據的時候是必須的,但是在以二進制格式抽取的時候是不必要的。 ``` unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length); ``` `from`參數指向一個字符串,比如應用到`bytea`字段時, `PQgetvalue`返回的。`PQunescapeBytea` 把它的字串表現形式轉換成二進制形式,它返回一個用`malloc()` 分配的指向該緩沖區的指針,或者是出錯時返回`NULL`,緩沖區的尺寸放在 `to_length`里。在不再需要這個結果之后, 這片內存必須用`PQfreemem`釋放。 這個轉換不正好是`PQescapeBytea`逆轉換,因為,當從 `PQgetvalue`接收時,字符串不希望被"逃逸"。尤其是,這意味著, 不需要考慮字符串引用,并且不需要`PGconn`參數。
                  <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>

                              哎呀哎呀视频在线观看