codekingpro/portable-devtools
114k
1<?xml version="1.0" encoding="UTF-8" standalone="no"?>2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>34.10. Functions Associated with the COPY Command</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets Vsnapshot" /><link rel="prev" href="libpq-notify.html" title="34.9. Asynchronous Notification" /><link rel="next" href="libpq-control.html" title="34.11. Control Functions" /></head><body id="docContent" class="container-fluid col-10"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">34.10. Functions Associated with the <code class="command">COPY</code> Command</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="libpq-notify.html" title="34.9. Asynchronous Notification">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><th width="60%" align="center">Chapter 34. <span class="application">libpq</span> — C Library</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 16.3 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="libpq-control.html" title="34.11. Control Functions">Next</a></td></tr></table><hr /></div><div class="sect1" id="LIBPQ-COPY"><div class="titlepage"><div><div><h2 class="title" style="clear: both">34.10. Functions Associated with the <code class="command">COPY</code> Command <a href="#LIBPQ-COPY" class="id_link">#</a></h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-SEND">34.10.1. Functions for Sending <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-RECEIVE">34.10.2. Functions for Receiving <code class="command">COPY</code> Data</a></span></dt><dt><span class="sect2"><a href="libpq-copy.html#LIBPQ-COPY-DEPRECATED">34.10.3. Obsolete Functions for <code class="command">COPY</code></a></span></dt></dl></div><a id="id-1.7.3.17.2" class="indexterm"></a><p>3 The <code class="command">COPY</code> command in4 <span class="productname">PostgreSQL</span> has options to read from or write5 to the network connection used by <span class="application">libpq</span>.6 The functions described in this section allow applications to take7 advantage of this capability by supplying or consuming copied data.8 </p><p>9 The overall process is that the application first issues the SQL10 <code class="command">COPY</code> command via <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or one11 of the equivalent functions. The response to this (if there is no12 error in the command) will be a <code class="structname">PGresult</code> object bearing13 a status code of <code class="literal">PGRES_COPY_OUT</code> or14 <code class="literal">PGRES_COPY_IN</code> (depending on the specified copy15 direction). The application should then use the functions of this16 section to receive or transmit data rows. When the data transfer is17 complete, another <code class="structname">PGresult</code> object is returned to indicate18 success or failure of the transfer. Its status will be19 <code class="literal">PGRES_COMMAND_OK</code> for success or20 <code class="literal">PGRES_FATAL_ERROR</code> if some problem was encountered.21 At this point further SQL commands can be issued via22 <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>. (It is not possible to execute other SQL23 commands using the same connection while the <code class="command">COPY</code>24 operation is in progress.)25 </p><p>26 If a <code class="command">COPY</code> command is issued via27 <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> in a string that could contain additional28 commands, the application must continue fetching results via29 <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> after completing the <code class="command">COPY</code>30 sequence. Only when <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> returns31 <code class="symbol">NULL</code> is it certain that the <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a>32 command string is done and it is safe to issue more commands.33 </p><p>34 The functions of this section should be executed only after obtaining35 a result status of <code class="literal">PGRES_COPY_OUT</code> or36 <code class="literal">PGRES_COPY_IN</code> from <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> or37 <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>.38 </p><p>39 A <code class="structname">PGresult</code> object bearing one of these status values40 carries some additional data about the <code class="command">COPY</code> operation41 that is starting. This additional data is available using functions42 that are also used in connection with query results:43 44 </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQNFIELDS-1"><span class="term"><code class="function">PQnfields</code><a id="id-1.7.3.17.7.3.1.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQNFIELDS-1" class="id_link">#</a></dt><dd><p>45 Returns the number of columns (fields) to be copied.46 </p></dd><dt id="LIBPQ-PQBINARYTUPLES-1"><span class="term"><code class="function">PQbinaryTuples</code><a id="id-1.7.3.17.7.3.2.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQBINARYTUPLES-1" class="id_link">#</a></dt><dd><p>47 0 indicates the overall copy format is textual (rows separated by48 newlines, columns separated by separator characters, etc.). 149 indicates the overall copy format is binary. See <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for more information.50 </p></dd><dt id="LIBPQ-PQFFORMAT-1"><span class="term"><code class="function">PQfformat</code><a id="id-1.7.3.17.7.3.3.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQFFORMAT-1" class="id_link">#</a></dt><dd><p>51 Returns the format code (0 for text, 1 for binary) associated with52 each column of the copy operation. The per-column format codes53 will always be zero when the overall copy format is textual, but54 the binary format can support both text and binary columns.55 (However, as of the current implementation of <code class="command">COPY</code>,56 only binary columns appear in a binary copy; so the per-column57 formats always match the overall format at present.)58 </p></dd></dl></div><p>59 </p><div class="sect2" id="LIBPQ-COPY-SEND"><div class="titlepage"><div><div><h3 class="title">34.10.1. Functions for Sending <code class="command">COPY</code> Data <a href="#LIBPQ-COPY-SEND" class="id_link">#</a></h3></div></div></div><p>60 These functions are used to send data during <code class="literal">COPY FROM61 STDIN</code>. They will fail if called when the connection is not in62 <code class="literal">COPY_IN</code> state.63 </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQPUTCOPYDATA"><span class="term"><code class="function">PQputCopyData</code><a id="id-1.7.3.17.8.3.1.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQPUTCOPYDATA" class="id_link">#</a></dt><dd><p>64 Sends data to the server during <code class="literal">COPY_IN</code> state.65</p><pre class="synopsis">66int PQputCopyData(PGconn *conn,67 const char *buffer,68 int nbytes);69</pre><p>70 </p><p>71 Transmits the <code class="command">COPY</code> data in the specified72 <em class="parameter"><code>buffer</code></em>, of length <em class="parameter"><code>nbytes</code></em>, to the server.73 The result is 1 if the data was queued, zero if it was not queued74 because of full buffers (this will only happen in nonblocking mode),75 or -1 if an error occurred.76 (Use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to retrieve details if77 the return value is -1. If the value is zero, wait for write-ready78 and try again.)79 </p><p>80 The application can divide the <code class="command">COPY</code> data stream81 into buffer loads of any convenient size. Buffer-load boundaries82 have no semantic significance when sending. The contents of the83 data stream must match the data format expected by the84 <code class="command">COPY</code> command; see <a class="xref" href="sql-copy.html" title="COPY"><span class="refentrytitle">COPY</span></a> for details.85 </p></dd><dt id="LIBPQ-PQPUTCOPYEND"><span class="term"><code class="function">PQputCopyEnd</code><a id="id-1.7.3.17.8.3.2.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQPUTCOPYEND" class="id_link">#</a></dt><dd><p>86 Sends end-of-data indication to the server during <code class="literal">COPY_IN</code> state.87</p><pre class="synopsis">88int PQputCopyEnd(PGconn *conn,89 const char *errormsg);90</pre><p>91 </p><p>92 Ends the <code class="literal">COPY_IN</code> operation successfully if93 <em class="parameter"><code>errormsg</code></em> is <code class="symbol">NULL</code>. If94 <em class="parameter"><code>errormsg</code></em> is not <code class="symbol">NULL</code> then the95 <code class="command">COPY</code> is forced to fail, with the string pointed to by96 <em class="parameter"><code>errormsg</code></em> used as the error message. (One should not97 assume that this exact error message will come back from the server,98 however, as the server might have already failed the99 <code class="command">COPY</code> for its own reasons.)100 </p><p>101 The result is 1 if the termination message was sent; or in102 nonblocking mode, this may only indicate that the termination103 message was successfully queued. (In nonblocking mode, to be104 certain that the data has been sent, you should next wait for105 write-ready and call <a class="xref" href="libpq-async.html#LIBPQ-PQFLUSH"><code class="function">PQflush</code></a>, repeating until it106 returns zero.) Zero indicates that the function could not queue107 the termination message because of full buffers; this will only108 happen in nonblocking mode. (In this case, wait for109 write-ready and try the <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTCOPYEND"><code class="function">PQputCopyEnd</code></a> call110 again.) If a hard error occurs, -1 is returned; you can use111 <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to retrieve details.112 </p><p>113 After successfully calling <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTCOPYEND"><code class="function">PQputCopyEnd</code></a>, call114 <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to obtain the final result status of the115 <code class="command">COPY</code> command. One can wait for this result to be116 available in the usual way. Then return to normal operation.117 </p></dd></dl></div></div><div class="sect2" id="LIBPQ-COPY-RECEIVE"><div class="titlepage"><div><div><h3 class="title">34.10.2. Functions for Receiving <code class="command">COPY</code> Data <a href="#LIBPQ-COPY-RECEIVE" class="id_link">#</a></h3></div></div></div><p>118 These functions are used to receive data during <code class="literal">COPY TO119 STDOUT</code>. They will fail if called when the connection is not in120 <code class="literal">COPY_OUT</code> state.121 </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQGETCOPYDATA"><span class="term"><code class="function">PQgetCopyData</code><a id="id-1.7.3.17.9.3.1.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQGETCOPYDATA" class="id_link">#</a></dt><dd><p>122 Receives data from the server during <code class="literal">COPY_OUT</code> state.123</p><pre class="synopsis">124int PQgetCopyData(PGconn *conn,125 char **buffer,126 int async);127</pre><p>128 </p><p>129 Attempts to obtain another row of data from the server during a130 <code class="command">COPY</code>. Data is always returned one data row at131 a time; if only a partial row is available, it is not returned.132 Successful return of a data row involves allocating a chunk of133 memory to hold the data. The <em class="parameter"><code>buffer</code></em> parameter must134 be non-<code class="symbol">NULL</code>. <em class="parameter"><code>*buffer</code></em> is set to135 point to the allocated memory, or to <code class="symbol">NULL</code> in cases136 where no buffer is returned. A non-<code class="symbol">NULL</code> result137 buffer should be freed using <a class="xref" href="libpq-misc.html#LIBPQ-PQFREEMEM"><code class="function">PQfreemem</code></a> when no longer138 needed.139 </p><p>140 When a row is successfully returned, the return value is the number141 of data bytes in the row (this will always be greater than zero).142 The returned string is always null-terminated, though this is143 probably only useful for textual <code class="command">COPY</code>. A result144 of zero indicates that the <code class="command">COPY</code> is still in145 progress, but no row is yet available (this is only possible when146 <em class="parameter"><code>async</code></em> is true). A result of -1 indicates that the147 <code class="command">COPY</code> is done. A result of -2 indicates that an148 error occurred (consult <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> for the reason).149 </p><p>150 When <em class="parameter"><code>async</code></em> is true (not zero),151 <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> will not block waiting for input; it152 will return zero if the <code class="command">COPY</code> is still in progress153 but no complete row is available. (In this case wait for read-ready154 and then call <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>155 </a> before calling156 <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> again.) When <em class="parameter"><code>async</code></em> is157 false (zero), <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> will block until data is158 available or the operation completes.159 </p><p>160 After <a class="xref" href="libpq-copy.html#LIBPQ-PQGETCOPYDATA"><code class="function">PQgetCopyData</code></a> returns -1, call161 <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> to obtain the final result status of the162 <code class="command">COPY</code> command. One can wait for this result to be163 available in the usual way. Then return to normal operation.164 </p></dd></dl></div></div><div class="sect2" id="LIBPQ-COPY-DEPRECATED"><div class="titlepage"><div><div><h3 class="title">34.10.3. Obsolete Functions for <code class="command">COPY</code> <a href="#LIBPQ-COPY-DEPRECATED" class="id_link">#</a></h3></div></div></div><p>165 These functions represent older methods of handling <code class="command">COPY</code>.166 Although they still work, they are deprecated due to poor error handling,167 inconvenient methods of detecting end-of-data, and lack of support for binary168 or nonblocking transfers.169 </p><div class="variablelist"><dl class="variablelist"><dt id="LIBPQ-PQGETLINE"><span class="term"><code class="function">PQgetline</code><a id="id-1.7.3.17.10.3.1.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQGETLINE" class="id_link">#</a></dt><dd><p>170 Reads a newline-terminated line of characters (transmitted171 by the server) into a buffer string of size <em class="parameter"><code>length</code></em>.172</p><pre class="synopsis">173int PQgetline(PGconn *conn,174 char *buffer,175 int length);176</pre><p>177 </p><p>178 This function copies up to <em class="parameter"><code>length</code></em>-1 characters into179 the buffer and converts the terminating newline into a zero byte.180 <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a> returns <code class="symbol">EOF</code> at the181 end of input, 0 if the entire line has been read, and 1 if the182 buffer is full but the terminating newline has not yet been read.183 </p><p>184 Note that the application must check to see if a new line consists185 of the two characters <code class="literal">\.</code>, which indicates186 that the server has finished sending the results of the187 <code class="command">COPY</code> command. If the application might receive188 lines that are more than <em class="parameter"><code>length</code></em>-1 characters long,189 care is needed to be sure it recognizes the <code class="literal">\.</code>190 line correctly (and does not, for example, mistake the end of a191 long data line for a terminator line).192 </p></dd><dt id="LIBPQ-PQGETLINEASYNC"><span class="term"><code class="function">PQgetlineAsync</code><a id="id-1.7.3.17.10.3.2.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQGETLINEASYNC" class="id_link">#</a></dt><dd><p>193 Reads a row of <code class="command">COPY</code> data (transmitted by the194 server) into a buffer without blocking.195</p><pre class="synopsis">196int PQgetlineAsync(PGconn *conn,197 char *buffer,198 int bufsize);199</pre><p>200 </p><p>201 This function is similar to <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a>, but it can be used202 by applications203 that must read <code class="command">COPY</code> data asynchronously, that is, without blocking.204 Having issued the <code class="command">COPY</code> command and gotten a <code class="literal">PGRES_COPY_OUT</code>205 response, the206 application should call <a class="xref" href="libpq-async.html#LIBPQ-PQCONSUMEINPUT"><code class="function">PQconsumeInput</code>207 </a> and208 <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a> until the209 end-of-data signal is detected.210 </p><p>211 Unlike <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a>, this function takes212 responsibility for detecting end-of-data.213 </p><p>214 On each call, <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a> will return data if a215 complete data row is available in <span class="application">libpq</span>'s input buffer.216 Otherwise, no data is returned until the rest of the row arrives.217 The function returns -1 if the end-of-copy-data marker has been recognized,218 or 0 if no data is available, or a positive number giving the number of219 bytes of data returned. If -1 is returned, the caller must next call220 <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>, and then return to normal processing.221 </p><p>222 The data returned will not extend beyond a data-row boundary. If possible223 a whole row will be returned at one time. But if the buffer offered by224 the caller is too small to hold a row sent by the server, then a partial225 data row will be returned. With textual data this can be detected by testing226 whether the last returned byte is <code class="literal">\n</code> or not. (In a binary227 <code class="command">COPY</code>, actual parsing of the <code class="command">COPY</code> data format will be needed to make the228 equivalent determination.)229 The returned string is not null-terminated. (If you want to add a230 terminating null, be sure to pass a <em class="parameter"><code>bufsize</code></em> one smaller231 than the room actually available.)232 </p></dd><dt id="LIBPQ-PQPUTLINE"><span class="term"><code class="function">PQputline</code><a id="id-1.7.3.17.10.3.3.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQPUTLINE" class="id_link">#</a></dt><dd><p>233 Sends a null-terminated string to the server. Returns 0 if234 OK and <code class="symbol">EOF</code> if unable to send the string.235</p><pre class="synopsis">236int PQputline(PGconn *conn,237 const char *string);238</pre><p>239 </p><p>240 The <code class="command">COPY</code> data stream sent by a series of calls241 to <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> has the same format as that242 returned by <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINEASYNC"><code class="function">PQgetlineAsync</code></a>, except that243 applications are not obliged to send exactly one data row per244 <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> call; it is okay to send a partial245 line or multiple lines per call.246 </p><div class="note"><h3 class="title">Note</h3><p>247 Before <span class="productname">PostgreSQL</span> protocol 3.0, it was necessary248 for the application to explicitly send the two characters249 <code class="literal">\.</code> as a final line to indicate to the server that it had250 finished sending <code class="command">COPY</code> data. While this still works, it is deprecated and the251 special meaning of <code class="literal">\.</code> can be expected to be removed in a252 future release. It is sufficient to call <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a> after253 having sent the actual data.254 </p></div></dd><dt id="LIBPQ-PQPUTNBYTES"><span class="term"><code class="function">PQputnbytes</code><a id="id-1.7.3.17.10.3.4.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQPUTNBYTES" class="id_link">#</a></dt><dd><p>255 Sends a non-null-terminated string to the server. Returns256 0 if OK and <code class="symbol">EOF</code> if unable to send the string.257</p><pre class="synopsis">258int PQputnbytes(PGconn *conn,259 const char *buffer,260 int nbytes);261</pre><p>262 </p><p>263 This is exactly like <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a>, except that the data264 buffer need not be null-terminated since the number of bytes to send is265 specified directly. Use this procedure when sending binary data.266 </p></dd><dt id="LIBPQ-PQENDCOPY"><span class="term"><code class="function">PQendcopy</code><a id="id-1.7.3.17.10.3.5.1.2" class="indexterm"></a></span> <a href="#LIBPQ-PQENDCOPY" class="id_link">#</a></dt><dd><p>267 Synchronizes with the server.268</p><pre class="synopsis">269int PQendcopy(PGconn *conn);270</pre><p>271 This function waits until the server has finished the copying.272 It should either be issued when the last string has been sent273 to the server using <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> or when the274 last string has been received from the server using275 <code class="function">PQgetline</code>. It must be issued or the server276 will get <span class="quote">“<span class="quote">out of sync</span>”</span> with the client. Upon return277 from this function, the server is ready to receive the next SQL278 command. The return value is 0 on successful completion,279 nonzero otherwise. (Use <a class="xref" href="libpq-status.html#LIBPQ-PQERRORMESSAGE"><code class="function">PQerrorMessage</code></a> to280 retrieve details if the return value is nonzero.)281 </p><p>282 When using <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a>, the application should283 respond to a <code class="literal">PGRES_COPY_OUT</code> result by executing284 <a class="xref" href="libpq-copy.html#LIBPQ-PQGETLINE"><code class="function">PQgetline</code></a> repeatedly, followed by285 <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a> after the terminator line is seen.286 It should then return to the <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> loop287 until <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> returns a null pointer.288 Similarly a <code class="literal">PGRES_COPY_IN</code> result is processed289 by a series of <a class="xref" href="libpq-copy.html#LIBPQ-PQPUTLINE"><code class="function">PQputline</code></a> calls followed by290 <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>, then return to the291 <a class="xref" href="libpq-async.html#LIBPQ-PQGETRESULT"><code class="function">PQgetResult</code></a> loop. This arrangement will292 ensure that a <code class="command">COPY</code> command embedded in a series293 of <acronym class="acronym">SQL</acronym> commands will be executed correctly.294 </p><p>295 Older applications are likely to submit a <code class="command">COPY</code>296 via <a class="xref" href="libpq-exec.html#LIBPQ-PQEXEC"><code class="function">PQexec</code></a> and assume that the transaction297 is done after <a class="xref" href="libpq-copy.html#LIBPQ-PQENDCOPY"><code class="function">PQendcopy</code></a>. This will work298 correctly only if the <code class="command">COPY</code> is the only299 <acronym class="acronym">SQL</acronym> command in the command string.300 </p></dd></dl></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="libpq-notify.html" title="34.9. Asynchronous Notification">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="libpq.html" title="Chapter 34. libpq — C Library">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="libpq-control.html" title="34.11. Control Functions">Next</a></td></tr><tr><td width="40%" align="left" valign="top">34.9. Asynchronous Notification </td><td width="20%" align="center"><a accesskey="h" href="index.html" title="PostgreSQL 16.3 Documentation">Home</a></td><td width="40%" align="right" valign="top"> 34.11. Control Functions</td></tr></table></div></body></html>