27.3. 命令執行函數

一旦與資料庫伺服器的連接成功建立,便可用這裡描述的函數執行 SQL 查詢和命令。

27.3.1. 主函數

PQexec

給伺服器提交一條命令並且等待結果。

PGresult *PQexec(PGconn *conn, const char *command);

返回一個PGresult指針或者也可能是一個 NULL 指針。 通常返回一個非空(non-NULL)的指針, 除非沒有內存或發生了象不能把命令發送到伺服器這樣的嚴重錯誤。 如果返回的是 NULL,它應該被當作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 的版本的時候會失敗。

如果使用了參數,那麼它們是以 $1$2,等等在命令字串中引用的。 nParams 是提供的參數的個數;它是數組 paramTypes[]paramValues[]paramLengths[],和 paramFormats[] 的長度。 (如果 nParams 是零,那麼數組指針可以是 NULL。) paramTypes[] 用 OID 的形式聲明了賦與參數符號的資料類型。 如果 paramTypesNULL,或者數組中任意元素是零, 那麼伺服器給對應的參數符號賦與和無類型文本串一樣的資料類型。 paramValues[] 聲明該參數的實際數值。這個數組中的空指針意味著對應的參數是空; 否則,這個指針指向一個空零結尾的文本字串(文本格式)或者伺服器期待的格式的二進制資料(用於二進制格式)。 paramLengths[] 聲明二進制格式參數的實際資料長度。 對於空參數和文本格式的參數會忽略這個參數。如果沒有二進制參數,那麼這個數組指針可以是空。 paramFormats[] 聲明某個參數是文本(在數組中放一個零)還是二進制(在數組中放一個1)。 如果這個數組指針是空,那麼所有參數都認為是文本的。 resultFormat 為零則獲取以文本方式返回的結果,為一則獲取以二進制形式返回的結果。 (目前不能規定從不同的字串獲取不同格式的結果,儘管對下層的協議是可能的。)

PQexecParamsPQexec 最主要的優勢是我們可以和命令串分開聲明參數值, 這樣就可以避免枯燥無聊並且很容易出錯的引起和逃逸。 和 PQexec 不同的是,PQexecParams 在一個給出的字串裡最多允許一個 SQL 命令。 (裡面可以有分號,但是不得超過一個非空的命令。)這是下層的協議的一個限制, 但是也有些額外的好處,比如可以有另外一層防止 SQL 注射攻擊的層次。

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 的方式聲明與參數符號關聯的資料類型。 如果 paramTypesNULL,或者數組中某個特定元素是零, 那麼伺服器將用處理無類型文本同樣的方法給這個參數符號賦予資料類型。 還有,查詢可以使用比 nParams 數值更大的參數符號編號; 這些參數的資料類型也是用一樣的方法推導的。

PQexec 類似,結果通常是一個 PGresult 對象, 其內容資料表明伺服器端是成功還是失敗。空的結果資料表示內存耗盡或者完全不能發送命令。 使用 PQerrorMessage 獲取有關這類錯誤的更多訊息。

目前,沒有任何方法可以幫助我們得到所推導出來的那些 paramTypes[] 裡面沒有聲明類型之參數的實際資料類型。 這是 libpq 的一個忽略,將來版本可能會糾正這點。

用於 PQexecPrepared 的準備好語句也可以透過執行 SQL PREPARE 語句來建立。 (不過 PQprepare 更靈活,因為它不要求預先聲明參數類型。) 還有,儘管沒有 libpq 函數可以刪除一個準備好語句, SQL DEALLOCATE 語句卻可以刪除。

PQexecPrepared

發送一個請求,執行一個帶有給出參數的準備好的語句,並且等待結果。

PGresult *PQexecPrepared(PGconn *conn,
                         const char *stmtName,
                         int nParams,
                         const char * const *paramValues,
                         const int *paramLengths,
                         const int *paramFormats,
                         int resultFormat);

PQexecPreparedPQexecParams 類似, 但是要執行的命令是透過命名一個前面準備好的語句聲明的,而不是給出一個查詢字串。 這個特性允許那些要重複使用的命令只進行一次分析和規劃,而不是每次執行都來一遍。 PQexecPrepared 只在協議 3.0 和以後的版本裡支援;在使用 2.0 版本的協議的時候,它們會失敗。

參數和 PQexecParams 一樣,只是給出的是一個準備好語句的名字,而不是一個查詢字串, 並且沒有 paramTypes[] 參數(沒必要,因為準備好語句的參數類型是在建立的時候確定的)。

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_TUPLES_OK, 那麼可以用下面的函數從查詢的返回中抽取資料訊息。 注意一個碰巧檢索了零條資料的SELECT仍然顯示 PGRES_TUPLES_OKPGRES_COMMAND_OK用於不返回資料的命令(INSERTUPDATE,等)。 返回 PGRES_EMPTY_QUERY 的響應通常意味著暴露了客戶端軟件裡面的臭蟲。

狀態為 PGRES_NONFATAL_ERROR 的結果永遠不會直接由 PQexec 或者其它查詢執行函數返回;這類的結果會被傳遞給通知處理器(參閱 Section 27.10)。

PQresStatus

PQresultStatus返回的枚舉類型轉換成一個描述狀態碼的字元串常量。 調用者不應該釋放結果。

char *PQresStatus(ExecStatusType status);

PQresultErrorMessage

返回與查詢關聯的錯誤訊息,或在沒有錯誤時返回一個空字元串。

char *PQresultErrorMessage(const PGresult *res);

如果有錯誤,那麼返回的字串將包括一個結尾的新行。 調用者不應該直接釋放結果。在相關的 PGresult 句柄傳遞給 PQclear 之後,它會自動釋放。

緊跟在一個 PQexecPQgetResult 調用後面,PQerrorMessage (對連接)將返回與 PQresultErrorMessage (對結果)一樣的字元串。 不過,一個PGresult將保有其錯誤訊息直到被刪除, 而連結的錯誤訊息將在後續的操作完成時被改變。當您想知道與某個 PGresult相關聯的狀態時用 PQresultErrorMessage;當您想知道與連接的最近一個操作相關聯的狀態時用 PQerrorMessage

PQresultErrorField

返回一個獨立的錯誤報告字串。

char *PQresultErrorField(const PGresult *res, int fieldcode);

fieldcode 是一個錯誤字串標識符;參閱下面列出的符號。 如果 PGresult 不是錯誤或者警告結果或者不包括指定的字串,那麼返回 NULL。 字串值通常將不包括結尾的新行。調用者不應該直接釋放結果。 在相關聯的 PGresult 句柄傳遞給 PQclear 之後,它將被自動釋放。

下列代碼是可用的:

PG_DIAG_SEVERITY

嚴重程度,這個字串的內容是 ERRORFATAL,或者 PANIC(在錯誤訊息裡),或者 WARNINGNOTICEDEBUGINFO,或者 LOG(在注意訊息裡), 或者是這些東西的一個本地化翻譯。總是出現。

PG_DIAG_SQLSTATE

這個錯誤的 SQLSTATE 代碼。SQLSTATE 代碼資料表示所發生的錯誤的類型; 可以由前端應用用於對特定的資料庫錯誤執行特定的操作(比如錯誤處理)。 關於可能的 SQLSTATE 代碼的列資料表,請參閱 Appendix A。 這個字串是不能區域化的,並且總是出現。

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_SOURCE_FILE

所報告的錯誤的原始碼位置的所在文件。

PG_DIAG_SOURCE_LINE

報告的這個錯誤所在的原始碼位置的行號。

PG_DIAG_SOURCE_FUNCTION

報告這個錯誤的原始碼函數的名字。

按照自身的要求格式化顯示訊息是客戶端的責任;特別是根據需要對長行進行折行。 在錯誤訊息字串裡出現的新行字元應該當作分段符號,而不是換行。

libpq 生成的錯誤將會有嚴重性和主訊息, 但是通常沒有其它字串。3.0 協議之前返回的錯誤將包含嚴重性和主訊息, 有時候還有詳細訊息,但是沒有其它字串。

請注意這些錯誤字串只能從 PGresult 對像裡獲得, 而不是 PGconn 對像;沒有 PQerrorField 函數。

PQclear

PQclear 釋放於PGresult相關聯的儲存空間。 任何不再需要的查詢結果在不需要的時候都應該用PQclear釋放掉。

void PQclear(PGresult *res);

只要您需要,您可以保留PGresult對像任意長的時間; 當您提交新的查詢時它並不消失,甚至您斷開連接後也是這樣。 要刪除它,您必須調用 PQclear。不這麼做將導致您的應用中的內存洩漏。

PQmakeEmptyPGresult

構造一個帶有給出的狀態的,空的PGresult對象。

PGresult* PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);

這是libpq的內部函數, 用於分配和初始化一個空PGresult對象。 它被輸出是因為一些應用需要自行生成結果對像(尤其是特定的帶有錯誤狀態的對象)。 如果conn非空(NULL)並且狀態指示一個錯誤, 連接目前的錯誤訊息被拷貝到PGresult。 注意最終對該對像還是要調用PQclear, 正如libpq本身返回的PGresult一樣。

27.3.2. 檢索查詢結果訊息

這些函數用於從一個代資料表著成功查詢結果(也就是說,狀態為 PGRES_TUPLES_OK 的查詢) 的 PGresult 對象。對於其它狀態值的對象,他們的行為會好像他們有零行和零列一樣。

PQntuples

返回查詢結果裡的行(資料)個數。

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返回在資料庫行裡面給該資料字串分配的空間, 換句話說就是該資料類型在伺服器裡的二進制形式的大小(尺寸)。 (因此,這個對客戶端沒有什麼用。) 如果該資料域是可變尺寸,返回 -1。

PQbinaryTuples

如果PGresult包含二進制資料資料時返回 1, 如果包含 ASCII 資料返回 0。

int PQbinaryTuples(const PGresult *res);

這個函數已經廢棄了(除了還用於與 COPY 連接之外),因為我們可能在一個 PGresult 的某些字串裡包含文本資料,而另外一些字串包含二進制資料。 更好的是使用 PQfformatPQbinaryTuples 只有在結果中的所有字串都是二進制(格式 1)的時候才返回 1。

PQgetvalue

返回一個PGresult 裡面一行的單獨的一個字串的值。 行和字串編號從 0 開始。調用者不應該直接釋放結果。在把 PGresult 句柄傳遞給 PQclear 之後,結果會被自動釋放。

char *PQgetvalue(const PGresult *res,
		 int row_number,
		 int column_number);

對於文本格式的資料, PQgetvalue 返回的值是一個資料表示字串值的空(NULL)結尾的字元串。 對於二進制格式, 返回的值就是由該資料類型的 typsendtypreceive 決定的二進製資料表現形式。 (在這種情況下,數值實際上也跟著一個字元零,但是通常這個字元沒什麼用處,因為數值本身很可能包含內嵌的空。)

如果字串值是空,則返回一個空字串。參閱 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);

這是某一特定資料值的實際資料長度。 行和字串編號從 0 開始。

int PQgetlength(const PGresult *res,
                int row_number,
                int column_number);

這是特定數值的實際資料長度,也就是說,PQgetvalue 指向的對象的大小。 對於文本資料格式,它和 strlen() 相同。對於二進制格式,這是潛在的訊息。 請注意我們應該依靠 PQfsize 獲取實際資料長度。

PQprint

向指定的輸出流打印所有的行和(可選的)字串名稱。

void PQprint(FILE *fout,      /* 輸出流 */
	     const PGresult *res,
	     const PQprintOpt *po);

struct {
    pqbool  header;      /* 打印輸出域頭和行計數 */
    pqbool  align;       /* 填充對齊各字串 */
    pqbool  standard;    /* 舊的傻格式 */
    pqbool  html3;       /* 輸出 HTML 資料表 */
    pqbool  expanded;    /* 擴展資料表 */
    pqbool  pager;       /* 必要時在輸出中使用分頁器 */
    char    *fieldSep;   /* 字串分隔符 */
    char    *tableOpt;   /* 在 HTML 中插入 table ... */
    char    *caption;    /* HTML caption */
    char    **fieldName; /* 替換字串名組成的空零結尾的數組 */
} PQprintOpt;

這個函數以前被 psql 用於打印查詢結果,但是現在已經不用這個函數了。請注意它假設所有的資料都是文本格式。

27.3.3. 檢索其它命令的結果訊息

這些函數用於從 PGresult 對像裡檢索那些非 SELECT 結果的訊息。

PQcmdStatus

返回產生PGresult的 SQL 命令的命令狀態字元串。

char *PQcmdStatus(PGresult *res);

通常這只是命令的名字,但是它可能包括額外的資料,比如處理過的行數。 調用者不應該釋放結果。結果會在把 PGresult 句柄傳遞給 PQclear 的時候釋放。

PQcmdTuples

返回被 SQL 命令影響的行的數量。

char *PQcmdTuples(PGresult *res);

這個函數返回一個生成這個 PGresult 的這個 SQL 語句影響的行數的字串。 這個函數只能用於 INSERTUPDATEDELETEMOVE, 或者 FETCH 語句執行之後的結果。或者是一個包含 INSERTUPDATE, 或者 DELETE 語句 EXECUTE 的一個準備好的查詢。 如果生成這個 PGresult 的命令是其他的東西,那麼 PQcmdTuples 返回一個空字串。 調用者不應該直接釋放返回的數值。在相關聯的 PGresult 被傳遞給 PQclear 之後,它會被自動釋放。

PQoidValue

返回一個插入的行的對象標識(OID)—— 如果SQL 命令是INSERT,或者是一個包含合適 INSERT 語句的準備好的 EXECUTE的時候。否則,函數返回 InvalidOid。如果受 INSERT 影響的資料表不包含 OID, 也返回 InvalidOid

Oid PQoidValue(const PGresult *res);

PQoidStatus

如果 SQL 命令是INSERT,或者包含合適 INSERT 的準備好語句 EXECUTE 了。返回一個被插入的行的 OID 的字串。 (如果 INSERT 並非恰好插入一行,或者目標資料表沒有OID,那麼字串將是 0。) 如果命令不是INSERT,則返回一個空字串。

char *PQoidStatus(const PGresult *res);

這個函數已經廢棄了,因為有了 PQoidValue,而且它也不是線程安全的。

27.3.4. 逃逸包含在 SQL 命令中的字串

PQescapeString為在 SQL 命令中使用字串而對之進行逃逸處理。 在我們向 SQL 命令裡把資料值當作文本常量插入的時候很有用。有些字元(比如單引號和反斜槓)必須被逃逸, 以避免他們被 SQL 分析器作為特殊字元解析。PQescapeString 執行這個操作。

提示: 如果我們從一個不可信的來源收到一個字串的話,那麼做恰當的逃逸就更重要了。 否則就有安全性危險:您會收到"SQL 注射"攻擊,這個時候會有您不想看到的 SQL 餵給您的資料庫。

請注意,如果一個資料值是作為 PQexecParams 或者同族函數的一個獨立參數傳遞的, 那麼逃逸就既不必要,也不正確。

size_t PQescapeString (char *to, const char *from, size_t length);

參數 from 指向將要逃逸的字串的第一個字元, length 參數給出在這個字串裡的字元數量。字串結尾的字元零不是必須的,也不計入 length。 (如果在處理 length 個字元之前出現了一個字元零, 那麼 PQescapeString 在這個字元零處停止; 這個行為類似 strncpy。) to 應該指向一個緩衝區,這個緩衝區至少能保存 length 數值的兩倍還多一個的字元,否則該函數行為將不可預測。 調用 PQescapeString 就會把逃逸的 from 字串轉換到 to 緩衝區,把特殊字元以免它們導致任何問題, 並且追加終止的字元零。那些必須包圍在PostgreSQL 字串文本周圍的單引號不算結果字串的一部分;您應該在把單引號放在插入這個處理結果的SQL命令周圍。

PQescapeString 返回寫到 to 裡面的字元數目, 不包括結尾的字元零。

如果 tofrom 字串相互重疊,那麼其行為不可預測。

27.3.5. 逃逸包含在 SQL 命令中的二進制字串

PQescapeBytea

逃逸那些在 SQL 命令中使用的用 bytea 資料表示的二進制資料。 和 PQescapeString 一樣,這個函數只有在直接向 SQL 字串插入資料的時候使用。

unsigned char *PQescapeBytea(const unsigned char *from,
				 size_t from_length,
				 size_t *to_length);

SQL 語句中用做 bytea 字串文本的一部分的時候, 有些字元值必需逃逸(但是對於所有字元而言是可以逃逸)。 通常,要逃逸一個字元,它是被轉換成一個三位八進制數字, 該數字數值等於該字元的數值,然後前綴兩個反斜槓。 單引號(')和反斜槓字元(\)有自己特殊的逃逸序列。參閱 Section 8.4 獲取更多訊息。 PQescapeBytea 執行這個操作,它只逃逸需要逃逸的最少的字元。

from 參數指向需要逃逸的字串的第一個字元, from_length 參數反映在這個二進制字串(結尾的字元零既不必要也不計算在內的字串)裡字元的個數。 to_length 參數應該是一個指向某個緩衝區的指針, 它的空間應該能夠保存逃逸後的結果字串長度。 結果字串長度不包括結果結尾的字元零。

PQescapeBytea 在內存重返回一個 from 參數的二進制字串的逃逸後的版本,這片內存是用 malloc() 分配的, 在結果不再需要的時候,必須用 PQfreemem() 釋放。 返回的字串已經把所有特殊的字元替換掉了,這樣他們就可以由 PostgreSQL的字串文本分析器以及 bytea 的輸入函數正確地處理。 同時還追加了一個結尾的字元零。那些必需包圍在 PostgreSQL字串文本周圍的單引號不算結果字串的一部分。

PQunescapeBytea

把一個二進制資料的逃逸後的字串資料表現形式轉換成二進制資料 — PQescapeBytea 的反作用。 在以文本格式抽取 bytea 資料的時候是必須的, 但是在以二進制格式抽取的時候是不必要的。

unsigned char *PQunescapeBytea(const unsigned char *from, size_t *to_length);

from 參數指向一個逃逸後的字串, 比如 PQgetvalue 處理過一個 bytea 字串後返回的。PQunescapeBytea 把它的字串資料表現形式轉換成二進制形式, 它返回一個用 malloc() 分配的指向該緩衝區的指針, 或者是出錯時返回空,緩衝區的尺寸放在 to_length 裡。 在不再需要這個結果之後,這片內存必須用 PQfreemem() 釋放。

PQfreemem

釋放 libpq 分配的內存。

void PQfreemem(void *ptr);

釋放由 libpq 分配的內存, 特別是 PQescapeByteaPQunescapeBytea, 和 PQnotifies。這是 Microsoft Windows 必須的, 因為它不能跨越 DLL 釋放內存,除非使用了多線程的 DLL (VC6 中的 /MD)。 在其它平台上,這個函數和標準的庫函數free()一樣。