⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecpg.sgml

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 SGML
📖 第 1 页 / 共 4 页
字号:
</programlisting>    This structure is suitable for interfacing with SQL datums of type    <type>varchar</type>.   </para>  </sect2>  <sect2>   <title><command>SELECT INTO</command> and <command>FETCH INTO</command></title>   <para>    Now you should be able to pass data generated by your program into    an SQL command.  But how do you retrieve the results of a query?    For that purpose, embedded SQL provides special variants of the    usual commands <command>SELECT</command> and    <command>FETCH</command>.  These commands have a special    <literal>INTO</literal> clause that specifies which host variables    the retrieved values are to be stored in.   </para>   <para>    Here is an example:<programlisting>/* * assume this table: * CREATE TABLE test1 (a int, b varchar(50)); */EXEC SQL BEGIN DECLARE SECTION;int v1;VARCHAR v2;EXEC SQL END DECLARE SECTION; ...EXEC SQL SELECT a, b INTO :v1, :v2 FROM test;</programlisting>    So the <literal>INTO</literal> clause appears between the select    list and the <literal>FROM</literal> clause.  The number of    elements in the select list and the list after    <literal>INTO</literal> (also called the target list) must be    equal.   </para>   <para>    Here is an example using the command <command>FETCH</command>:<programlisting>EXEC SQL BEGIN DECLARE SECTION;int v1;VARCHAR v2;EXEC SQL END DECLARE SECTION; ...EXEC SQL DECLARE foo CURSOR FOR SELECT a, b FROM test; ...do {    ...    EXEC SQL FETCH NEXT FROM foo INTO :v1, :v2;    ...} while (...);</programlisting>    Here the <literal>INTO</literal> clause appears after all the    normal clauses.   </para>   <para>    Both of these methods only allow retrieving one row at a time.  If    you need to process result sets that potentially contain more than    one row, you need to use a cursor, as shown in the second example.   </para>  </sect2>  <sect2>   <title>Indicators</title>   <para>    The examples above do not handle null values.  In fact, the    retrieval examples will raise an error if they fetch a null value    from the database.  To be able to pass null values to the database    or retrieve null values from the database, you need to append a    second host variable specification to each host variable that    contains data.  This second host variable is called the    <firstterm>indicator</firstterm> and contains a flag that tells    whether the datum is null, in which case the value of the real    host variable is ignored.  Here is an example that handles the    retrieval of null values correctly:<programlisting>EXEC SQL BEGIN DECLARE SECTION;VARCHAR val;int val_ind;EXEC SQL END DECLARE SECTION: ...EXEC SQL SELECT b INTO :val :val_ind FROM test1;</programlisting>    The indicator variable <varname>val_ind</varname> will be zero if    the value was not null, and it will be negative if the value was    null.   </para>   <para>    The indicator has another function: if the indicator value is    positive, it means that the value is not null, but it was    truncated when it was stored in the host variable.   </para>  </sect2> </sect1> <sect1 id="ecpg-dynamic">  <title>Dynamic SQL</title>  <para>   In many cases, the particular SQL statements that an application   has to execute are known at the time the application is written.   In some cases, however, the SQL statements are composed at run time   or provided by an external source.  In these cases you cannot embed   the SQL statements directly into the C source code, but there is a   facility that allows you to call arbitrary SQL statements that you   provide in a string variable.  </para>  <para>   The simplest way to execute an arbitrary SQL statement is to use   the command <command>EXECUTE IMMEDIATE</command>.  For example:<programlisting>EXEC SQL BEGIN DECLARE SECTION;const char *stmt = "CREATE TABLE test1 (...);";EXEC SQL END DECLARE SECTION;EXEC SQL EXECUTE IMMEDIATE :stmt;</programlisting>   You may not execute statements that retrieve data (e.g.,   <command>SELECT</command>) this way.  </para>  <para>   A more powerful way to execute arbitrary SQL statements is to   prepare them once and execute the prepared statement as often as   you like.  It is also possible to prepare a generalized version of   a statement and then execute specific versions of it by   substituting parameters.  When preparing the statement, write   question marks where you want to substitute parameters later.  For   example:<programlisting>EXEC SQL BEGIN DECLARE SECTION;const char *stmt = "INSERT INTO test1 VALUES(?, ?);";EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE mystmt FROM :stmt; ...EXEC SQL EXECUTE mystmt USING 42, 'foobar';</programlisting>   If the statement you are executing returns values, then add an   <literal>INTO</literal> clause:<programlisting>EXEC SQL BEGIN DECLARE SECTION;const char *stmt = "SELECT a, b, c FROM test1 WHERE a &gt; ?";int v1, v2;VARCHAR v3;EXEC SQL END DECLARE SECTION;EXEC SQL PREPARE mystmt FROM :stmt; ...EXEC SQL EXECUTE mystmt INTO v1, v2, v3 USING 37;</programlisting>   An <command>EXECUTE</command> command may have an   <literal>INTO</literal> clause, a <literal>USING</literal> clause,   both, or neither.  </para>  <para>   When you don't need the prepared statement anymore, you should   deallocate it:<programlisting>EXEC SQL DEALLOCATE PREPARE <replaceable>name</replaceable>;</programlisting>  </para> </sect1> <sect1 id="ecpg-descriptors">  <title>Using SQL Descriptor Areas</title>  <para>   An SQL descriptor area is a more sophisticated method for   processing the result of a <command>SELECT</command> or   <command>FETCH</command> statement.  An SQL descriptor area groups   the data of one row of data together with metadata items into one   data structure.  The metadata is particularly useful when executing   dynamic SQL statements, where the nature of the result columns may   not be known ahead of time.  </para>  <para>   An SQL descriptor area consists of a header, which contains   information concerning the entire descriptor, and one or more item   descriptor areas, which basically each describe one column in the   result row.  </para>  <para>   Before you can use an SQL descriptor area, you need to allocate one:<programlisting>EXEC SQL ALLOCATE DESCRIPTOR <replaceable>identifier</replaceable>;</programlisting>   The identifier serves as the <quote>variable name</quote> of the   descriptor area.  <remark>The scope of the allocated descriptor is WHAT?.</remark>   When you don't need the descriptor anymore, you should deallocate   it:<programlisting>EXEC SQL DEALLOCATE DESCRIPTOR <replaceable>identifier</replaceable>;</programlisting>  </para>  <para>   To use a descriptor area, specify it as the storage target in an   <literal>INTO</literal> clause, instead of listing host variables:<programlisting>EXEC SQL FETCH NEXT FROM mycursor INTO DESCRIPTOR mydesc;</programlisting>  </para>  <para>   Now how do you get the data out of the descriptor area?  You can   think of the descriptor area as a structure with named fields.  To   retrieve the value of a field from the header and store it into a   host variable, use the following command:<programlisting>EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;</programlisting>   Currently, there is only one header field defined:   <replaceable>COUNT</replaceable>, which tells how many item   descriptor areas exist (that is, how many columns are contained in   the result).  The host variable needs to be of an integer type.  To   get a field from the item descriptor area, use the following   command:<programlisting>EXEC SQL GET DESCRIPTOR <replaceable>name</replaceable> VALUE <replaceable>num</replaceable> :<replaceable>hostvar</replaceable> = <replaceable>field</replaceable>;</programlisting>   <replaceable>num</replaceable> can be a literal integer or a host   variable containing an integer. Possible fields are:   <variablelist>    <varlistentry>     <term><literal>CARDINALITY</literal> (integer)</term>     <listitem>      <para>       number of rows in the result set      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>DATA</literal></term>     <listitem>      <para>       actual data item (therefore, the data type of this field       depends on the query)      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>DATETIME_INTERVAL_CODE</literal> (integer)</term>     <listitem>      <para>       ?      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>DATETIME_INTERVAL_PRECISION</literal> (integer)</term>     <listitem>      <para>       not implemented      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>INDICATOR</literal> (integer)</term>     <listitem>      <para>       the indicator (indicating a null value or a value truncation)      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>KEY_MEMBER</literal> (integer)</term>     <listitem>      <para>       not implemented      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>LENGTH</literal> (integer)</term>     <listitem>      <para>       length of the datum in characters      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>NAME</literal> (string)</term>     <listitem>      <para>       name of the column      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>NULLABLE</literal> (integer)</term>     <listitem>      <para>       not implemented      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>OCTET_LENGTH</literal> (integer)</term>     <listitem>      <para>       length of the character representation of the datum in bytes      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>PRECISION</literal> (integer)</term>     <listitem>      <para>       precision (for type <type>numeric</type>)      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>RETURNED_LENGTH</literal> (integer)</term>     <listitem>      <para>       length of the datum in characters      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>RETURNED_OCTET_LENGTH</literal> (integer)</term>     <listitem>      <para>       length of the character representation of the datum in bytes      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>SCALE</literal> (integer)</term>     <listitem>      <para>       scale (for type <type>numeric</type>)      </para>     </listitem>    </varlistentry>    <varlistentry>     <term><literal>TYPE</literal> (integer)</term>     <listitem>      <para>       numeric code of the data type of the column      </para>     </listitem>    </varlistentry>   </variablelist>  </para> </sect1> <sect1 id="ecpg-errors">  <title>Error Handling</title>  <para>   This section describes how you can handle exceptional conditions   and warnings in an embedded SQL program.  There are several   nonexclusive facilities for this.  </para>  <sect2>   <title>Setting Callbacks</title>   <para>    One simple method to catch errors and warnings is to set a    specific action to be executed whenever a particular condition    occurs.  In general:<programlisting>EXEC SQL WHENEVER <replaceable>condition</replaceable> <replaceable>action</replaceable>;</programlisting>   </para>   <para>    <replaceable>condition</replaceable> can be one of the following:    <variablelist>     <varlistentry>      <term><literal>SQLERROR</literal></term>      <listitem>       <para>        The specified action is called whenever an error occurs during        the execution of an SQL statement.       </para>      </listitem>     </varlistentry>     <varlistentry>      <term><literal>SQLWARNING</literal></term>      <listitem>       <para>        The specified action is called whenever a warning occurs        during the execution of an SQL statement.       </para>      </listitem>     </varlistentry>     <varlistentry>      <term><literal>NOT FOUND</literal></term>      <listitem>       <para>        The specified action is called whenever an SQL statement        retrieves or affects zero rows.  (This condition is not an        error, but you might be interested in handling it specially.)       </para>      </listitem>     </varlistentry>    </variablelist>   </para>   <para>    <replaceable>action</replaceable> can be one of the following:    <variablelist>     <varlistentry>      <term><literal>CONTINUE</literal></term>      <listitem>       <para>        This effectively means that the condition is ignored.  This is        the default.       </para>      </listitem>     </varlistentry>     <varlistentry>      <term><literal>GOTO <replaceable>label</replaceable></literal></term>      <term><literal>GO TO <replaceable>label</replaceable></literal></term>      <listitem>       <para>        Jump to the specified label (using a C <literal>goto</literal>        statement).       </para>      </listitem>     </varlistentry>     <varlistentry>      <term><literal>SQLPRINT</literal></term>      <listitem>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -