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

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 31.9\. 與`COPY`命令相關的函數 PostgreSQL里的`COPY`命令里有用于 libpq從網絡連接讀出或者寫入的選項。 本節描述的函數允許應用通過提供或者消耗拷貝數據,充分利用這個功能。 整個過程是應用首先通過`PQexec`或者一個等效的函數發出 `COPY`命令。對這個命令的響應(如果命令無誤) 將是一個帶著狀態碼`PGRES_COPY_OUT`或者`PGRES_COPY_IN` 的`PGresult`(具體根據聲明的拷貝方向)。 應用然后就應該使用本節的函數接受或者發送數據行。在數據傳輸結束之后, 返回另外一個`PGresult`對象以表明傳輸的成功或者失敗。它的狀態將是 `PGRES_COMMAND_OK`表示成功或者如果發生了一些問題,是 `PGRES_FATAL_ERROR`。這個時候開始我們可以通過`PQexec` 發出更多 SQL 命令。(`COPY`操作在處理的過程中, 我們不可能用同一個連接執行其它 SQL 命令。 如果一個`COPY`是通過`PQexec` 在一個可以包含額外命令的字串里發出的,那么應用在完成`COPY` 序列之后必須繼續用`PQgetResult`抓取結果。只有在`PQgetResult` 返回`NULL`的時候,我們才能確信`PQexec` 的命令字串已經處理完畢,并且已經可以安全地發出更多命令。 本節的這些函數應該只在從`PQexec`或`PQgetResult` 獲得了`PGRES_COPY_OUT`或`PGRES_COPY_IN`結果狀態的情況下執行。 一個承載了這些狀態值之一地`PGresult`對象運載了某些有關正在開始的 `COPY`操作的額外信息。這些額外的數據可以用那些同時也處理查詢結果的函數獲取。 `PQnfields` 返回要拷貝的字段(數據域)個數 `PQbinaryTuples` 0 表示全部拷貝格式都是文本的(行之間用換行分隔,字段用分隔符分隔,等等)。 1 表示全部拷貝格式都是二進制。參閱[COPY](#calibre_link-777)獲取更多信息。 `PQfformat` 返回和拷貝操作的每個字段相關的格式代碼(0 是文本,1 是二進制)。 如果全部拷貝格式是文本,那么每字段的格式碼將總是零,但是(整體) 二進制格式可以支持文本和二進制字段并存。(不過,就目前的`COPY`實現, 在二進制拷貝里只出現二進制字段;所以目前每字段的格式總是匹配整體格式。) > **Note:** 這些額外的數據值只能在使用 3.0 版本的協議的時候獲得。在使用 2.0 版本的協議時,所有這些函數都返回 0。 ## 31.9.1\. 用于發送`COPY`數據的函數 這些函數用于在`COPY FROM STDIN`過程中發送數據。 如果在連接不是處于`COPY_IN`狀態下,它們會失敗。 `PQputCopyData` 在`COPY_IN`狀態里向服務器發送數據。 ``` int PQputCopyData(PGconn *conn, const char *buffer, int nbytes); ``` 傳輸指定的`buffer`里的,長度為`nbytes`的`COPY` 數據到服務器。如果數據發送成功,結果是 1,如果因為發送企圖會阻塞 (這種情況只有在連接是非阻塞模式時才有可能)而沒有成功,那么是零, 或者是在發生錯誤的時候是 -1。(如果返回 -1,那么使用`PQerrorMessage` 檢索細節。如果值是零,那么等待寫準備好然后重試。) 應用可以把`COPY`數據流分隔成任意合適的大小放到緩沖區里。在發送的時候, 緩沖區的邊界沒有什么特殊的語意。數據流的內容必須匹配`COPY`命令預期的數據格式; 參閱[COPY](#calibre_link-777)獲取細節。 `PQputCopyEnd` 在`COPY_IN`狀態里向服務器發送數據完畢的指示。 ``` int PQputCopyEnd(PGconn *conn, const char *errormsg); ``` 如果`errormsg`是`NULL`,則成功結束`COPY_IN`操作。 如果`errormsg`不是`NULL`則`COPY`操作被強制失敗, `errormsg`指向的字串是錯誤信息。(我們不能認為同樣的信息可能會從服務器傳回, 因為服務器可能已經因為自己的原因讓`COPY`失敗。 還要注意的是在使用 3.0 版本之前的協議連接時,強制失敗的選項是不能用的。) 如果終止數據發送,則結果為 1,如果發送企圖會阻塞(只有在連接是在非阻塞模式的情況下才可能出現這個情況), 則為零,如果發生錯誤則返回 -1。(如果返回值是 -1,用`PQerrorMessage` 檢索細節。如果值是零,那么等待寫準備好然后重新嘗試。) 在成功調用`PQputCopyEnd`之后,調用`PQgetResult`獲取`COPY` 命令的最終結果狀態。我們可以用平常的方法來等待這個結果可用。然后返回到正常的操作。 ## 31.9.2\. 用于接收`COPY`數據的函數 這些函數用于在`COPY TO STDOUT`的過程中檢索數據。 如果連接不在`COPY_OUT`狀態,那么他們將會失敗。 `PQgetCopyData` 在`COPY_OUT`狀態下從服務器接收數據。 ``` int PQgetCopyData(PGconn *conn, char **buffer, int async); ``` 在一個`COPY`的過程中試圖從服務器獲取另外一行數據。數據總是每次返回一個數據行; 如果只有一部分行可用,那么它不會被返回。成功返回一個數據行包括分配一個內存塊來保存這些數據。 `buffer`參數必須是非`NULL`。`*buffer` 設置為指向分配出來的內存的指針,或者是如果沒有返回緩沖區,那么為`NULL`。 一個非`NULL`的結果緩沖區在不再需要的時候必須用`PQfreemem`釋放。 在成功返回一行之后,那么返回的值就是該數據行里數據的字節數(這個將總是大于零)。 返回的字串總是空結尾的,雖然可能只是對文本的`COPY`有用。 一個零的結果表示該`COPY`仍然在處理中,但是還沒有可以用的行 (這個只有在`async`為真的時候才可能)。一個結果為 -1 的值表示 `COPY`已經結束。結果為 -2 表示發生了錯誤(參考`PQerrorMessage`獲取原因)。 在`async`為真的時候(非零),`PQgetCopyData`將不會阻塞住等待輸入; 如果該`COPY`仍在處理過程中并且沒有可用的完整行,那么它將返回零。 (在這種情況下它等待讀準備好,然后在再次調用`PQgetCopyData`之前, 調用`PQconsumeInput`。)在`async`是假(零)的時候, `PQgetCopyData`將阻塞住,直到數據可用或者操作完成。 在`PQgetCopyData`返回 -1 之后,調用`PQgetResult`獲取 `COPY`命令的最后結果狀態。我們可以用通常的方法等待這個結果可用。然后返回到正常操作。 ## 31.9.3\. 用于`COPY`的廢棄的函數 下面的這些函數代表了以前的處理`COPY`的方法。盡管他們還能用,但是現在已經廢棄了, 因為他們的錯誤處理實在是太糟糕了,并且檢測數據結束的方法也很不方便,并且缺少對二進制和非阻塞傳輸的支持。 `PQgetline` 讀取一個以新行符結尾的字符行(由服務器傳輸)到一個長度為`length`的字符串緩沖區。 ``` int PQgetline(PGconn *conn, char *buffer, int length); ``` 這個函數拷貝最多`length`-1個字符到緩沖區里,然后把終止的新行符轉換成一個字節零。 `PQgetline`在輸入結束時返回`EOF`,如果整行都被讀取了返回 0, 如果緩沖區填滿了而還沒有遇到結束的新行符則返回 1。 注意,應用程序必須檢查新行是否包含兩個字符`\.`, 這表明服務器已經完成了`COPY`命令的結果的發送。 如果應用可能收到超過`length`-1字符長的字符,我們就應該確保正確識別 `\.`行(例如,不要把一個長的數據行的結束當作一個終止行)。 `PQgetlineAsync` 不阻塞地讀取一行`COPY`數據(由服務器傳輸)到一個緩沖區中。 ``` int PQgetlineAsync(PGconn *conn, char *buffer, int bufsize); ``` 這個函數類似于`PQgetline`,但是可以用于那些必須異步讀取`COPY` 數據的應用,也就是不阻塞的應用。在使用了`COPY`命令和獲取了`PGRES_COPY_OUT` 響應之后,應用應該調用`PQconsumeInput`和`PQgetlineAsync` 直到收到數據結束的信號。 不像`PQgetline`,這個函數負責檢測數據結束。 在每次調用時,如果libpq的輸入緩沖區內有可用的一個完整的數據行, `PQgetlineAsync`都將返回數據。否則,在其他數據到達之前不會返回數據。 如果見到了拷貝數據結束的標志,此函數返回 -1,如果沒有可用數據, 或者是給出一個正數表明返回的數據的字節數,返回 0。如果返回 -1,調用者下一步必須調用 `PQendcopy`,然后回到正常處理。 返回的數據將不超過一行的范圍。如果可能,每次將返回一個完整行。但如果調用者提供的緩沖區太小, 無法容下服務器發出的整行,那么將返回部分行。對于文本數據,這個可以通過測試返回的最后一個字節是否是 `\n`來確認。(在二進制`COPY`中,我們需要對`COPY` 數據格式進行實際的分析,以便做相同的判斷。)返回的字符串不是空結尾的。(如果你想得到一個空結尾的字串, 確保你傳遞了一個比實際可用空間少一字節的`bufsize`。) `PQputline` 向服務器發送一個空結尾的字符串。成功時返回 0,如果不能發送字符串返回`EOF`。 ``` int PQputline(PGconn *conn, const char *string); ``` 一系列`PQputline`調用發送的`COPY`數據流和 `PQgetlineAsync`返回的數據有著一樣的格式,只是應用不需要明確地在每次 `PQputline`調用中發送一個數據行;每次調用發送多行或者部分行都是可以的。 > **Note:** 在PostgreSQL協議3.0之前,應用必須明確的發送兩個字符`\.` 作為行結束,向服務器表明它已經完成了發送`COPY`數據。雖然這個仍然工作, 但是已經廢棄了,并且`\.`的特殊含義在將來的版本中有望刪除。 在發送實際數據之后調用`PQendcopy`就足夠了。 `PQputnbytes` 向服務器發送一個非空結尾的字符串。成功時返回 0,如果不能發送字符串返回`EOF`。 ``` int PQputnbytes(PGconn *conn, const char *buffer, int nbytes); ``` 此函數類似`PQputline`,除了數據緩沖區不需要是空結尾的之外, 因為要發送的字節數是直接聲明的。在發送二進制數據的時候使用這個過程。 `PQendcopy` 與服務器同步。 ``` int PQendcopy(PGconn *conn); ``` 這個函數將等待直到服務器完成拷貝。你可以在用`PQputline` 向服務器發送完最后一個字符串后或者用`PGgetline` 從服務器獲取最后一行字符串后調用它。我們必須調用這個函數,否則服務器可能會和前端 "不同步"。在這個函數返回后,服務器就已經準備好接收下一個 SQL 命令了。 成功時返回0,否則返回非零值。(如果返回值為非 0,用`PQerrorMessage`檢索細節。) 在使用`PQgetResult`時,應用應該對`PGRES_COPY_OUT` 的結果做出反應:重復調用`PQgetline`,并且在收到結束行時調用 `PQendcopy`。然后應該返回到`PQgetResult` 循環直到`PQgetResult`返回空指針。類似地,`PGRES_COPY_IN` 結果是用一系列`PQputline`調用最后跟著`PQendcopy`, 然后返回到`PQgetResult`循環。這樣的排列將保證嵌入到一系列 SQL命令里的`COPY`命令將被正確執行。 舊的應用大多通過`PQexec`提交一個`COPY` 命令并且假設在`PQendcopy`后事務完成。這樣只有在`COPY` 是命令字串里的唯一的SQL命令時才能正確工作。
                  <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>

                              哎呀哎呀视频在线观看