diff options
author | Michael Meskes <meskes@postgresql.org> | 2010-01-26 09:10:11 +0000 |
---|---|---|
committer | Michael Meskes <meskes@postgresql.org> | 2010-01-26 09:10:11 +0000 |
commit | 96b8d5842cd6e991a44a01c128b1c3de821e882b (patch) | |
tree | b4a7fdaa680efc11eaaf0bbbc13d6acf2feef711 | |
parent | aa6ac352215d435b277711f85985d00a07a5c590 (diff) | |
download | postgresql-96b8d5842cd6e991a44a01c128b1c3de821e882b.tar.gz postgresql-96b8d5842cd6e991a44a01c128b1c3de821e882b.zip |
Finally applied patch by Boszormenyi Zoltan <zb@cybertec.at> to add the new features his patches added to the docs.
-rw-r--r-- | doc/src/sgml/ecpg.sgml | 993 |
1 files changed, 789 insertions, 204 deletions
diff --git a/doc/src/sgml/ecpg.sgml b/doc/src/sgml/ecpg.sgml index ebf8e73a845..bb164e23e74 100644 --- a/doc/src/sgml/ecpg.sgml +++ b/doc/src/sgml/ecpg.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.93 2009/12/02 14:07:25 momjian Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.94 2010/01/26 09:10:11 meskes Exp $ --> <chapter id="ecpg"> <title><application>ECPG</application> - Embedded <acronym>SQL</acronym> in C</title> @@ -2376,6 +2376,478 @@ void PGTYPESdecimal_free(decimal *var); </sect2> </sect1> + <sect1 id="ecpg-descriptors"> + <title>Using Descriptor Areas</title> + + <para> + An SQL descriptor area is a more sophisticated method for processing + the result of a <command>SELECT</command>, <command>FETCH</command> or + a <command>DESCRIBE</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 might + not be known ahead of time. PostgreSQL provides two ways to use + Descriptor Areas: the named SQL Descriptor Areas and the C-structure + SQLDAs. + </para> + + <sect2 id="ecpg-named-descriptors"> + <title>Named SQL Descriptor Areas</title> + + <para> + A named 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 SQL DESCRIPTOR mydesc; +</programlisting> + If the resultset is empty, the Descriptor Area will still contain + the metadata from the query, i.e. the field names. + </para> + + <para> + For not yet executed prepared queries, the <command>DESCRIBE</command> + statement can be used to get the metadata of the resultset: +<programlisting> +EXEC SQL BEGIN DECLARE SECTION; +char *sql_stmt = "SELECT * FROM table1"; +EXEC SQL END DECLARE SECTION; + +EXEC SQL PREPARE stmt1 FROM :sql_stmt; +EXEC SQL DESCRIBE stmt1 INTO SQL DESCRIPTOR mydesc; +</programlisting> + </para> + + <para> + Before PostgreSQL 8.5, the <literal>SQL</literal> keyword was optional, + so using <literal>DESCRIPTOR</literal> and <literal>SQL DESCRIPTOR</literal> + produced named SQL Descriptor Areas. Now it is mandatory, omitting + the <literal>SQL</literal> keyword produces SQLDA Descriptor Areas, + see <xref linkend="ecpg-sqlda-descriptors">. + </para> + + <para> + In <command>DESCRIBE</command> and <command>FETCH</command> statements, + the <literal>INTO</literal> and <literal>USING</literal> keywords can be + used to similarly: they produce the resultset and the metadata in a + Descriptor Area. + </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> + + <para> + In <command>EXECUTE</command>, <command>DECLARE</command> and <command>OPEN</command> + statements, the effect of the <literal>INTO</literal> and <literal>USING</literal> + keywords are different. A Descriptor Area can also be manually built to + provide the input parameters for a query or a cursor and + <literal>USING SQL DESCRIPTOR <replaceable>name</replaceable></literal> + is the way to pass the input parameters into a parametrized query. The statement + to build a named SQL Descriptor Area is below: +<programlisting> +EXEC SQL SET DESCRIPTOR <replaceable>name</replaceable> VALUE <replaceable>num</replaceable> <replaceable>field</replaceable> = :<replaceable>hostvar</replaceable>; +</programlisting> + </para> + + <para> + PostgreSQL supports retrieving more that one record in one <command>FETCH</command> + statement and storing the data in host variables in this case assumes that the + variable is an array. E.g.: +<programlisting> +EXEC SQL BEGIN DECLARE SECTION; +int id[5]; +EXEC SQL END DECLARE SECTION; + +EXEC SQL FETCH 5 FROM mycursor INTO SQL DESCRIPTOR mydesc; + +EXEC SQL GET DESCRIPTOR mydesc VALUE 1 :id = DATA; +</programlisting> + + </para> + + </sect2> + + <sect2 id="ecpg-sqlda-descriptors"> + <title>SQLDA Descriptor Areas</title> + + <para> + An SQLDA Descriptor Area is a C language structure which can be also used + to get the resultset and the metadata of a query. One structure stores one + record from the resultset. +<programlisting> +EXEC SQL include sqlda.h; +sqlda_t *mysqlda; + +EXEC SQL FETCH 3 FROM mycursor INTO DESCRIPTOR mysqlda; +</programlisting> + Note that the <literal>SQL</literal> keyword is omitted. The paragraphs about + the use cases of the <literal>INTO</literal> and <literal>USING</literal> + keywords in <xref linkend="ecpg-named-descriptors"> also apply here with an addition. + In a <command>DESCRIBE</command> statement the <literal>DESCRIPTOR</literal> + keyword can be completely omitted if the <literal>INTO</literal> keyword is used: +<programlisting> +EXEC SQL DESCRIBE prepared_statement INTO mysqlda; +</programlisting> + </para> + + <para> + The structure of SQLDA is: +<programlisting> +#define NAMEDATALEN 64 + +struct sqlname +{ + short length; + char data[NAMEDATALEN]; +}; + +struct sqlvar_struct +{ + short sqltype; + short sqllen; + char *sqldata; + short *sqlind; + struct sqlname sqlname; +}; + +struct sqlda_struct +{ + char sqldaid[8]; + long sqldabc; + short sqln; + short sqld; + struct sqlda_struct *desc_next; + struct sqlvar_struct sqlvar[1]; +}; + +typedef struct sqlvar_struct sqlvar_t; +typedef struct sqlda_struct sqlda_t; +</programlisting> + </para> + + <para> + The allocated data for an SQLDA structure is variable as it depends on the + number of fields in a resultset and also depends on the length of the string + data values in a record. The individual fields of the <literal>SQLDA</literal> + structure are: + + <variablelist> + <varlistentry> + <term><literal>sqldaid</></term> + <listitem> + <para> + It contains the "<literal>SQLDA </literal>" literal string. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>sqldabc</></term> + <listitem> + <para> + It contains the size of the allocated space in bytes. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>sqln</></term> + <listitem> + <para> + It contains the number of input parameters for a parametrized query + case it's passed into <command>OPEN</command>, <command>DECLARE</command> or + <command>EXECUTE</command> statements using the <literal>USING</literal> + keyword. In case it's used as output of <command>SELECT</command>, + <command>EXECUTE</command> or <command>FETCH</command> statements, + its value is the same as <literal>sqld</literal> + statement + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>sqld</></term> + <listitem> + <para> + It contains the number of fields in a resultset. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>desc_next</></term> + <listitem> + <para> + If the query returns more than one records, multiple linked SQLDA structures + are returned, the first record is stored in the SQLDA returned in the + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>sqlvar</></term> + <listitem> + <para> + This is the array of the fields in the resultset. The fields are: + + <variablelist> + + <varlistentry> + <term><literal>sqltype</></term> + <listitem> + <para> + It contains the type identifier of the field. For values, + see <literal>enum ECPGttype</literal> in <literal>ecpgtype.h</literal>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqllen</></term> + <listitem> + <para> + It contains the binary length of the field. E.g. 4 bytes for ECPGt_int. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqldata</></term> + <listitem> + <para> + <literal>(char *)sqldata</literal> points to the data. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlind</></term> + <listitem> + <para> + <literal>(char *)sqlind</literal> points to the NULL indicator for data. + 0 means NOT NULL, -1 means NULL. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlname</></term> + <listitem> + <para> + <literal>struct sqlname sqlname</literal> contains the name of the field + in a structure: +<programlisting> +struct sqlname +{ + short length; + char data[NAMEDATALEN]; +}; +</programlisting> + + <variablelist> + <varlistentry> + <term><literal>length</></term> + <listitem> + <para> + <literal>sqlname.length</literal> contains the length of the field name. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>data</></term> + <listitem> + <para> + <literal>sqlname.data</literal> contains the actual field name. + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + </listitem> + </varlistentry> + + </variablelist> + </para> + </listitem> + </varlistentry> + </variablelist> + </para> + + </sect2> + + </sect1> + <sect1 id="ecpg-informix-compat"> <title><productname>Informix</productname> compatibility mode</title> <para> @@ -2420,7 +2892,23 @@ void PGTYPESdecimal_free(decimal *var); </para> <sect2> - <title>Additional embedded SQL statements</title> + <title>Additional types</title> + <para> + The Informix-special "string" pseudo-type for storing right-trimmed character string data is now + supported in Informix-mode without using <literal>typedef</literal>. In fact, in Informix-mode, + ECPG refuses to process source files that contain <literal>typedef sometype string;</literal> +<programlisting> + EXEC SQL BEGIN DECLARE SECTION; + string userid; /* this variable will contain trimmed data */ + EXEC SQL END DECLARE SECTION; + + EXEC SQL FETCH MYCUR INTO :userid; +</programlisting> + </para> + </sect2> + + <sect2> + <title>Additional/missing embedded SQL statements</title> <para> <variablelist> <varlistentry> @@ -2436,11 +2924,310 @@ void PGTYPESdecimal_free(decimal *var); </para> </listitem> </varlistentry> + <varlistentry> + <term><literal>FREE cursor_name</></term> + <listitem> + <para> + Due to the differences how ECPG works compared to Informix's ESQL/C (i.e. which steps + are purely grammar transformations and which steps rely on the underlying runtime library) + there is no <literal>FREE cursor_name</> statement in ECPG. This is because in ECPG, + <literal>DECLARE CURSOR</literal> doesn't translate to a function call into + the runtime library that uses to the cursor name. This means that there's no runtime + bookkeeping of SQL cursors in the ECPG runtime library, only in the PostgreSQL server. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><literal>FREE statement_name</></term> + <listitem> + <para> + <literal>FREE statement_name</> is a synonym for <literal>DEALLOCATE PREPARE statement_name</>. + </para> + </listitem> + </varlistentry> </variablelist> </para> </sect2> <sect2> + <title>Informix-compatible SQLDA Descriptor Areas</title> + <para> + Informix-compatible mode supports a different structure than the one described in + <xref linkend="ecpg-sqlda-descriptors">. See below: +<programlisting> +struct sqlvar_compat +{ + short sqltype; + int sqllen; + char *sqldata; + short *sqlind; + char *sqlname; + char *sqlformat; + short sqlitype; + short sqlilen; + char *sqlidata; + int sqlxid; + char *sqltypename; + short sqltypelen; + short sqlownerlen; + short sqlsourcetype; + char *sqlownername; + int sqlsourceid; + + char *sqlilongdata; + int sqlflags; + void *sqlreserved; +}; + +struct sqlda_compat +{ + short sqld; + struct sqlvar_compat *sqlvar; + char desc_name[19]; + short desc_occ; + struct sqlda_compat *desc_next; + void *reserved; +}; + +typedef struct sqlvar_compat sqlvar_t; +typedef struct sqlda_compat sqlda_t; +</programlisting> + </para> + + <para> + The global properties are: + <variablelist> + + <varlistentry> + <term><literal>sqld</></term> + <listitem> + <para> + The number of fields in the <literal>SQLDA</> descriptor. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlvar</></term> + <listitem> + <para> + Pointer to the per-field properties. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>desc_name</></term> + <listitem> + <para> + Unused, filled with zerobytes. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>desc_occ</></term> + <listitem> + <para> + Size of the allocated structure. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>desc_next</></term> + <listitem> + <para> + Pointer to the next SQLDA structure if the resultset contains more than one records. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>reserved</></term> + <listitem> + <para> + Unused pointer, contains NULL. Kept for Informix-compatibility. + </para> + </listitem> + </varlistentry> + + </variablelist> + + The per-field properties are below, they are stored in the <literal>sqlvar</literal> array: + + <variablelist> + + <varlistentry> + <term><literal>sqltype</></term> + <listitem> + <para> + Type of the field. Constants are in <literal>sqltypes.h</literal> + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqllen</></term> + <listitem> + <para> + Length of the field data. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqldata</></term> + <listitem> + <para> + Pointer to the field data. The pointer is of <literal>char *</literal> type, + the data pointed by it is in a binary format. Example: +<programlisting> + int intval; + + switch (sqldata->sqlvar[i].sqltype) + { + case SQLINTEGER: + intval = *(int *)sqldata->sqlvar[i].sqldata; + break; + ... + } +</programlisting> + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlind</></term> + <listitem> + <para> + Pointer to the NULL indicator. If returned by DESCRIBE or FETCH then it's always a valid pointer. + If used as input for <literal>EXECUTE ... USING sqlda;</literal> then NULL-pointer value means + that the value for this field is non-NULL. Otherwise a valid pointer and <literal>sqlitype</literal> + has to be properly set. Example: +<programlisting> + if (*(int2 *)sqldata->sqlvar[i].sqlind != 0) + printf("value is NULL\n"); +</programlisting> + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlname</></term> + <listitem> + <para> + Name of the field. 0-terminated string. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlformat</></term> + <listitem> + <para> + Reserved in Informix, value of PQfformat() for the field. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlitype</></term> + <listitem> + <para> + Type of the NULL indicator data. It's always SQLSMINT when returning data from the server. + When the <literal>SQLDA</literal> is used for a parametrized query, the data is treated + according to the set type. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlilen</></term> + <listitem> + <para> + Length of the NULL indicator data. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlxid</></term> + <listitem> + <para> + Extended type of the field, result of PQftype(). + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqltypename</></term> + <term><literal>sqltypelen</></term> + <term><literal>sqlownerlen</></term> + <term><literal>sqlsourcetype</></term> + <term><literal>sqlownername</></term> + <term><literal>sqlsourceid</></term> + <term><literal>sqlflags</></term> + <term><literal>sqlreserved</></term> + <listitem> + <para> + Unused. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sqlilongdata</></term> + <listitem> + <para> + It equals to <literal>sqldata</literal> if <literal>sqllen</literal> is larger than 32KB. + </para> + </listitem> + </varlistentry> + + </variablelist> + + Example: +<programlisting> +EXEC SQL INCLUDE sqlda.h; + + sqlda_t *sqlda; /* This doesn't need to be under embedded DECLARE SECTION */ + + EXEC SQL BEGIN DECLARE SECTION; + char *prep_stmt = "select * from table1"; + int i; + EXEC SQL END DECLARE SECTION; + + ... + + EXEC SQL PREPARE mystmt FROM :prep_stmt; + + EXEC SQL DESCRIBE mystmt INTO sqlda; + + printf("# of fields: %d\n", sqlda->sqld); + for (i = 0; i < sqlda->sqld; i++) + printf("field %d: \"%s\"\n", sqlda->sqlvar[i]->sqlname); + + EXEC SQL DECLARE mycursor CURSOR FOR mystmt; + EXEC SQL OPEN mycursor; + EXEC SQL WHENEVER NOT FOUND GOTO out; + + while (1) + { + EXEC SQL FETCH mycursor USING sqlda; + } + + EXEC SQL CLOSE mycursor; + + free(sqlda); /* The main structure is all to be free(), + * sqlda and sqlda->sqlvar is in one allocated area */ +</programlisting> + For more information, see the <literal>sqlda.h</> header and the + <literal>src/interfaces/ecpg/test/compat_informix/sqlda.pgc</literal> regression test. + </para> + </sect2> + + <sect2> <title>Additional functions</title> <para> <variablelist> @@ -3660,208 +4447,6 @@ risnull(CINTTYPE, (char *) &i); </sect2> </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 might - 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> |