1998-07-29 14:50:04 +08:00
|
|
|
<Chapter Id="ecpg">
|
1998-03-01 16:16:16 +08:00
|
|
|
<DocInfo>
|
|
|
|
<AuthorGroup>
|
|
|
|
<Author>
|
2000-03-03 17:56:03 +08:00
|
|
|
<FirstName>Linus</FirstName>
|
1998-03-01 16:16:16 +08:00
|
|
|
<Surname>Tolke</Surname>
|
|
|
|
</Author>
|
|
|
|
<Author>
|
|
|
|
<FirstName>Michael</FirstName>
|
|
|
|
<Surname>Meskes</Surname>
|
|
|
|
</Author>
|
|
|
|
</AuthorGroup>
|
|
|
|
<Copyright>
|
|
|
|
<Year>1996-1997</Year>
|
|
|
|
<Holder>Linus Tolke</Holder>
|
|
|
|
</Copyright>
|
|
|
|
<Copyright>
|
|
|
|
<Year>1998</Year>
|
|
|
|
<Holder>Michael Meskes</Holder>
|
|
|
|
</Copyright>
|
|
|
|
<Date>Transcribed 1998-02-12</Date>
|
|
|
|
</DocInfo>
|
|
|
|
|
1998-10-11 01:12:18 +08:00
|
|
|
<Title><Application>ecpg</Application> - Embedded <Acronym>SQL</Acronym>
|
|
|
|
in <Acronym>C</Acronym></Title>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
This describes an embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym>
|
|
|
|
package for <ProductName>Postgres</ProductName>.
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
It is written by <ULink url="mailto:linus@epact.se">Linus Tolke</ULink>
|
1999-03-24 22:54:10 +08:00
|
|
|
and <ULink url="mailto:meskes@postgresql.org">Michael Meskes</ULink>.
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Note>
|
|
|
|
<Para>
|
|
|
|
Permission is granted to copy and use in the same way as you are allowed
|
|
|
|
to copy and use the rest of the <ProductName>PostgreSQL</ProductName>.
|
|
|
|
</Para>
|
|
|
|
</Note>
|
1998-12-29 10:24:47 +08:00
|
|
|
</para>
|
1998-03-01 16:16:16 +08:00
|
|
|
<Sect1>
|
|
|
|
<Title>Why Embedded <Acronym>SQL</Acronym>?</Title>
|
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
Embedded <Acronym>SQL</Acronym> has some small advantages over other ways
|
|
|
|
to handle <Acronym>SQL</Acronym>
|
1998-03-01 16:16:16 +08:00
|
|
|
queries. It takes care of all the tedious moving of information to and
|
1998-10-11 01:12:18 +08:00
|
|
|
from variables in your <Acronym>C</Acronym> program.
|
|
|
|
Many <Acronym>RDBMS</Acronym> packages
|
1998-03-01 16:16:16 +08:00
|
|
|
support this embedded language.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
1998-09-21 13:55:23 +08:00
|
|
|
<Para> There is an ANSI-standard describing how the embedded language should
|
1998-10-11 01:12:18 +08:00
|
|
|
work. <Application>ecpg</Application> was designed to meet this standard
|
|
|
|
as much as possible. So it is
|
1998-09-21 13:55:23 +08:00
|
|
|
possible to port programs with embedded <Acronym>SQL</Acronym> written for
|
|
|
|
other <Acronym>RDBMS</Acronym> packages to
|
|
|
|
<ProductName>Postgres</ProductName> and thus promoting the spirit of free
|
|
|
|
software.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
<Sect1>
|
|
|
|
<Title>The Concept</Title>
|
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
You write your program in <Acronym>C</Acronym> with some
|
|
|
|
special <Acronym>SQL</Acronym> things.
|
|
|
|
For declaring variables that can be used in
|
|
|
|
<Acronym>SQL</Acronym> statements you need to
|
1998-03-01 16:16:16 +08:00
|
|
|
put them in a special declare section.
|
|
|
|
You use a special syntax for the <Acronym>SQL</Acronym> queries.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
Before compiling you run the file through
|
|
|
|
the embedded <Acronym>SQL</Acronym> <Acronym>C</Acronym>
|
|
|
|
preprocessor and it converts the <Acronym>SQL</Acronym> statements you used
|
|
|
|
to function
|
1998-03-01 16:16:16 +08:00
|
|
|
calls with the variables used as arguments. Both variables that are used
|
1998-10-11 01:12:18 +08:00
|
|
|
as input to the <Acronym>SQL</Acronym> statements and variables that will
|
|
|
|
contain the
|
1998-03-01 16:16:16 +08:00
|
|
|
result are passed.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
Then you compile and at link time you link with a special library that
|
|
|
|
contains the functions used. These functions (actually it is mostly one
|
|
|
|
single function) fetches the information from the arguments, performs
|
1998-10-11 01:12:18 +08:00
|
|
|
the <Acronym>SQL</Acronym> query using the ordinary interface
|
|
|
|
(<FileName>libpq</FileName>) and puts back
|
1998-03-01 16:16:16 +08:00
|
|
|
the result in the arguments dedicated for output.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
Then you run your program and when the control arrives to
|
|
|
|
the <Acronym>SQL</Acronym>
|
|
|
|
statement the <Acronym>SQL</Acronym> statement is performed against
|
|
|
|
the database and you
|
1998-03-01 16:16:16 +08:00
|
|
|
can continue with the result.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title>How To Use <Application>egpc</Application></Title>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
This section describes how to use the <Application>egpc</Application> tool.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect2>
|
1998-12-29 10:24:47 +08:00
|
|
|
<Title>Preprocessor</title>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
The preprocessor is called <Application>ecpg</Application>.
|
|
|
|
After installation it resides in
|
1998-03-01 16:16:16 +08:00
|
|
|
the <ProductName>Postgres</ProductName> <FileName>bin/</FileName> directory.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect2>
|
1998-03-01 16:16:16 +08:00
|
|
|
<Sect2>
|
1998-12-29 10:24:47 +08:00
|
|
|
<Title>Library</title>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
The <Application>ecpg</Application> library is called
|
|
|
|
<FileName>libecpg.a</FileName> or
|
1998-03-01 16:16:16 +08:00
|
|
|
<FileName>libecpg.so</FileName>. Additionally, the library
|
|
|
|
uses the <FileName>libpq</FileName> library for communication to the
|
|
|
|
<ProductName>Postgres</ProductName> server so you will
|
|
|
|
have to link your program with <Parameter>-lecpg -lpq</Parameter>.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
The library has some methods that are "hidden" but that could prove very
|
|
|
|
useful sometime.
|
|
|
|
|
1998-10-11 01:12:18 +08:00
|
|
|
<itemizedlist>
|
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
<function>ECPGdebug(int <replaceable class="parameter">on</replaceable>, FILE *<replaceable class="parameter">stream</replaceable>)</function>
|
|
|
|
turns on debug logging if called with the first argument non-zero.
|
|
|
|
Debug logging is done on <replaceable class="parameter">stream</replaceable>.
|
|
|
|
Most <Acronym>SQL</Acronym> statement logs its arguments and result.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
The most important one (<Function>ECPGdo</Function>)
|
1999-03-24 22:54:10 +08:00
|
|
|
that is called on almost all <Acronym>SQL</Acronym>
|
|
|
|
statements logs both its expanded string,
|
1998-10-11 01:12:18 +08:00
|
|
|
i.e. the string
|
1998-03-01 16:16:16 +08:00
|
|
|
with all the input variables inserted, and the result from the
|
1998-10-11 01:12:18 +08:00
|
|
|
<ProductName>Postgres</ProductName> server.
|
|
|
|
This can be very useful when searching for errors
|
1998-03-01 16:16:16 +08:00
|
|
|
in your <Acronym>SQL</Acronym> statements.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
|
1998-10-11 01:12:18 +08:00
|
|
|
<listitem>
|
|
|
|
<para>
|
|
|
|
<function>ECPGstatus()</function>
|
1998-03-01 16:16:16 +08:00
|
|
|
This method returns TRUE if we are connected to a database and FALSE if not.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
1998-10-11 01:12:18 +08:00
|
|
|
</itemizedlist>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect2>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect2>
|
1998-12-29 10:24:47 +08:00
|
|
|
<Title>Error handling</title>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
To be able to detect errors from the <ProductName>Postgres</ProductName>
|
|
|
|
server you include a line like
|
1998-03-01 16:16:16 +08:00
|
|
|
<ProgramListing>
|
|
|
|
exec sql include sqlca;
|
|
|
|
</ProgramListing>
|
|
|
|
in the include section of your file. This will define a struct and a
|
|
|
|
variable with the name <Parameter>sqlca</Parameter> as following:
|
|
|
|
<ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
struct sqlca
|
|
|
|
{
|
|
|
|
char sqlcaid[8];
|
|
|
|
long sqlabc;
|
|
|
|
long sqlcode;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int sqlerrml;
|
|
|
|
char sqlerrmc[70];
|
|
|
|
} sqlerrm;
|
|
|
|
char sqlerrp[8];
|
|
|
|
long sqlerrd[6];
|
|
|
|
/* 0: empty */
|
1999-09-15 22:14:10 +08:00
|
|
|
/* 1: OID of processed tuple if applicable */
|
1999-03-24 22:54:10 +08:00
|
|
|
/* 2: number of rows processed in an INSERT, UPDATE */
|
|
|
|
/* or DELETE statement */
|
|
|
|
/* 3: empty */
|
|
|
|
/* 4: empty */
|
|
|
|
/* 5: empty */
|
|
|
|
char sqlwarn[8];
|
|
|
|
/* 0: set to 'W' if at least one other is 'W' */
|
|
|
|
/* 1: if 'W' at least one character string */
|
|
|
|
/* value was truncated when it was */
|
|
|
|
/* stored into a host variable. */
|
|
|
|
/* 2: empty */
|
|
|
|
/* 3: empty */
|
|
|
|
/* 4: empty */
|
|
|
|
/* 5: empty */
|
|
|
|
/* 6: empty */
|
|
|
|
/* 7: empty */
|
|
|
|
char sqlext[8];
|
1998-03-01 16:16:16 +08:00
|
|
|
} sqlca;
|
|
|
|
</ProgramListing>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
If an error occured in the last <Acronym>SQL</Acronym> statement
|
|
|
|
then <Parameter>sqlca.sqlcode</Parameter>
|
|
|
|
will be non-zero. If <Parameter>sqlca.sqlcode</Parameter> is less that 0
|
|
|
|
then this is
|
1998-03-01 16:16:16 +08:00
|
|
|
some kind of serious error, like the database definition does not match
|
|
|
|
the query given. If it is bigger than 0 then this is a normal error like
|
|
|
|
the table did not contain the requested row.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
sqlca.sqlerrm.sqlerrmc will contain a string that describes the error.
|
1999-03-24 22:54:10 +08:00
|
|
|
The string ends with the line number
|
|
|
|
in the source file.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
List of errors that can occur:
|
|
|
|
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-12, Out of memory in line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Does not normally occur. This is a sign that your virtual memory is
|
|
|
|
exhausted.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-200, Unsupported type %s on line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Does not normally occur. This is a sign that the preprocessor has
|
|
|
|
generated something that the library does not know about. Perhaps you
|
|
|
|
are running incompatible versions of the preprocessor and the library.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-201, Too many arguments line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
This means that <ProductName>Postgres</ProductName> has returned more
|
|
|
|
arguments than we have
|
|
|
|
matching variables. Perhaps you have forgotten a couple of the host
|
|
|
|
variables in the <Command>INTO :var1,:var2</Command>-list.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-202, Too few arguments line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
This means that <ProductName>Postgres</ProductName> has returned fewer
|
|
|
|
arguments than we have
|
|
|
|
host variables. Perhaps you have too many host variables in the
|
|
|
|
<Command>INTO :var1,:var2</Command>-list.
|
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-203, Too many matches line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
This means that the query has returned several lines but the
|
|
|
|
variables specified are no arrays. The <Command>SELECT</Command> you made
|
|
|
|
probably was not unique.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-204, Not correctly formatted int type: %s line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
This means that the host variable is of an <Type>int</Type> type and the field
|
1998-10-11 01:12:18 +08:00
|
|
|
in the <ProductName>Postgres</ProductName> database is of another type and
|
|
|
|
contains a value that cannot be interpreted as an <Type>int</Type>.
|
|
|
|
The library uses <Function>strtol</Function>
|
1998-03-01 16:16:16 +08:00
|
|
|
for this conversion.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-205, Not correctly formatted unsigned type: %s line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
This means that the host variable is of an <Type>unsigned int</Type> type and
|
1998-10-11 01:12:18 +08:00
|
|
|
the field in the <ProductName>Postgres</ProductName> database is of another
|
|
|
|
type and contains a
|
1998-03-01 16:16:16 +08:00
|
|
|
value that cannot be interpreted as an <Type>unsigned int</Type>. The library
|
|
|
|
uses <Function>strtoul</Function> for this conversion.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-206, Not correctly formatted floating point type: %s line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
This means that the host variable is of a <Type>float</Type> type and
|
1998-10-11 01:12:18 +08:00
|
|
|
the field in the <ProductName>Postgres</ProductName> database is of another
|
|
|
|
type and contains a
|
1998-03-01 16:16:16 +08:00
|
|
|
value that cannot be interpreted as an <Type>float</Type>. The library
|
|
|
|
uses <Function>strtod</Function> for this conversion.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-207, Unable to convert %s to bool on line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
This means that the host variable is of a <Type>bool</Type> type and
|
|
|
|
the field in the <ProductName>Postgres</ProductName> database is neither 't'
|
|
|
|
nor 'f'.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-208, Empty query line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
<ProductName>Postgres</ProductName> returned PGRES_EMPTY_QUERY, probably
|
|
|
|
because the query indeed was empty.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-220, No such connection %s in line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
The program tries to access a connection that does not exist.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-221, Not connected in line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
The program tries to access a connection that does exist but is not open.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-230, Invalid statement name %s in line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
The statement you are trying to use has not been prepared.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-400, Postgres error: %s line %d.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Some <ProductName>Postgres</ProductName> error.
|
|
|
|
The message contains the error message from the
|
|
|
|
<ProductName>Postgres</ProductName> backend.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-401, Error in transaction processing line %d. </Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
<ProductName>Postgres</ProductName> signalled to us that we cannot start,
|
|
|
|
commit or rollback the transaction.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>-402, connect: could not open database %s.</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
The connect to the database did not work.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>100, Data not found line %d.</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
This is a "normal" error that tells you that what you are quering cannot
|
|
|
|
be found or we have gone through the cursor.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
1998-03-01 16:16:16 +08:00
|
|
|
</VariableList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
</Sect2>
|
1998-12-29 10:24:47 +08:00
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title>Limitations</Title>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
What will never be included and why or what cannot be done with this
|
|
|
|
concept.
|
|
|
|
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>oracles single tasking possibility</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
Oracle version 7.0 on AIX 3 uses the OS-supported locks on the shared
|
|
|
|
memory segments and allows the application designer to link an
|
|
|
|
application in a so called single tasking way. Instead of starting one
|
|
|
|
client process per application process both the database part and the
|
|
|
|
application part is run in the same process. In later versions of oracle
|
|
|
|
this is no longer supported.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
This would require a total redesign of the <ProductName>Postgres</ProductName> access model and
|
|
|
|
that effort can not justify the performance gained.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title>Porting From Other <Acronym>RDBMS</Acronym> Packages</Title>
|
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
The design of <Application>ecpg</Application> follows SQL standard. So
|
|
|
|
porting from a standard RDBMS should not be a problem. Unfortunately there
|
|
|
|
is no such thing as a standard RDBMS. So <Application>ecpg</Application>
|
|
|
|
also tries to understand syntax additions as long as they do not create
|
|
|
|
conflicts with the standard.
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
The following list shows all the known incompatibilities. If you find one
|
|
|
|
not listed please notify <ULink url="mailto:meskes@postgresql.org">Michael
|
|
|
|
Meskes</ULink>. Note, however, that we list only incompatibilities from
|
|
|
|
a precompiler of another RDBMS to <Application>ecpg</Application> and not
|
|
|
|
additional <Application>ecpg</Application> features that these RDBMS do not
|
|
|
|
have.
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Syntax of FETCH command</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
The standard syntax of the FETCH command is:
|
1999-03-30 23:20:43 +08:00
|
|
|
</para>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Para>
|
|
|
|
FETCH [direction] [amount] IN|FROM <Replaceable>cursor name</Replaceable>.
|
|
|
|
</Para>
|
1999-03-30 23:20:43 +08:00
|
|
|
<para>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Application>ORACLE</Application>, however, does not use the keywords IN
|
|
|
|
resp. FROM. This feature cannot be added since it would create parsing
|
|
|
|
conflicts.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1999-04-06 23:41:20 +08:00
|
|
|
</Para>
|
1998-12-29 10:24:47 +08:00
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title>Installation</Title>
|
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
Since version 0.5 <Application>ecpg</Application> is distributed
|
|
|
|
together with <ProductName>Postgres</ProductName>. So you
|
1998-03-01 16:16:16 +08:00
|
|
|
should get your precompiler, libraries and header files compiled and
|
1998-10-11 01:12:18 +08:00
|
|
|
installed by default as a part of your installation.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect1>
|
|
|
|
<Title>For the Developer</Title>
|
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
This section is for those who want to develop the
|
|
|
|
<Application>ecpg</Application> interface. It
|
1998-03-01 16:16:16 +08:00
|
|
|
describes how the things work. The ambition is to make this section
|
|
|
|
contain things for those that want to have a look inside and the section
|
|
|
|
on How to use it should be enough for all normal questions.
|
|
|
|
|
1998-10-11 01:12:18 +08:00
|
|
|
So, read this before looking at the internals of the
|
|
|
|
<Application>ecpg</Application>. If
|
1998-03-01 16:16:16 +08:00
|
|
|
you are not interested in how it really works, skip this section.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect2>
|
|
|
|
<Title>ToDo List</Title>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
This version the preprocessor has some flaws:
|
|
|
|
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>Library functions</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
to_date et al. do not exists. But then <ProductName>Postgres</ProductName>
|
|
|
|
has some good conversion routines itself. So you probably won't miss these.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>Structures ans unions</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Structures and unions have to be defined in the declare section.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>Missing statements</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-09-21 13:55:23 +08:00
|
|
|
The following statements are not implemented thus far:
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term> exec sql allocate</Term>
|
1998-09-30 13:41:54 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</listitem>
|
1998-09-21 13:55:23 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term> exec sql deallocate</Term>
|
1998-09-30 13:41:54 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</listitem>
|
1998-09-21 13:55:23 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term> SQLSTATE</Term>
|
1998-09-30 13:41:54 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</listitem>
|
1998-09-21 13:55:23 +08:00
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>message 'no data found'</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-09-21 13:55:23 +08:00
|
|
|
The error message for "no data" in an exec sql insert select from statement
|
|
|
|
has to be 100.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Term>sqlwarn[6]</Term>
|
1998-03-01 16:16:16 +08:00
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-09-21 13:55:23 +08:00
|
|
|
sqlwarn[6] should be 'W' if the PRECISION or SCALE value specified in a SET
|
|
|
|
DESCRIPTOR statement will be ignored.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect2>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect2>
|
|
|
|
<Title>The Preprocessor</Title>
|
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
The first four lines written to the output are constant additions by ecpg.
|
|
|
|
These are two comments and two include lines necessary for the interface to the
|
|
|
|
library.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Then the preprocessor works in one pass only, reading the input file and
|
1998-03-01 16:16:16 +08:00
|
|
|
writing to the output as it goes along. Normally it just echoes
|
|
|
|
everything to the output without looking at it further.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
When it comes to an <Command>EXEC SQL</Command> statements it intervenes and
|
|
|
|
changes them depending on what it is.
|
1998-10-11 01:12:18 +08:00
|
|
|
The <Command>EXEC SQL</Command> statement can be one of these:
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Declare sections</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
Declare sections begins with
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql begin declare section;
|
|
|
|
</ProgramListing>
|
|
|
|
and ends with
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql end declare section;
|
|
|
|
</ProgramListing>
|
|
|
|
In the section only variable declarations are allowed. Every variable
|
|
|
|
declare within this section is also entered in a list of variables
|
|
|
|
indexed on their name together with the corresponding type.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
1999-03-24 22:54:10 +08:00
|
|
|
<Para>
|
|
|
|
In particular the definition of a structure or union also has to be listed
|
|
|
|
inside a declare section. Otherwise <Application>ecpg</Application> cannot
|
|
|
|
handle these types since it simply does not know the definition.
|
|
|
|
</Para>
|
|
|
|
|
1998-03-01 16:16:16 +08:00
|
|
|
<Para>
|
|
|
|
The declaration is echoed to the file to make the variable a normal
|
|
|
|
C-variable also.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
The special types VARCHAR and VARCHAR2 are converted into a named struct
|
|
|
|
for every variable. A declaration like:
|
|
|
|
<ProgramListing>
|
|
|
|
VARCHAR var[180];
|
|
|
|
</ProgramListing>
|
|
|
|
is converted into
|
|
|
|
<ProgramListing>
|
|
|
|
struct varchar_var { int len; char arr[180]; } var;
|
|
|
|
</ProgramListing>
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Include statements</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
An include statement looks like:
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql include filename;
|
|
|
|
</ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
Not that this is NOT the same as
|
1998-03-01 16:16:16 +08:00
|
|
|
<ProgramListing>
|
|
|
|
#include <filename.h>
|
|
|
|
</ProgramListing>
|
|
|
|
</Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
Instead the file specified is parsed by <Application>ecpg</Application>
|
|
|
|
itself. So the contents of the specified file is included in the resulting C
|
|
|
|
code. This way you are able to specify EXEC SQL commands in an include file.
|
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Connect statement</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
A connect statement looks like:
|
|
|
|
<ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
exec sql connect to <Replaceable>connection target</Replaceable>;
|
1998-03-01 16:16:16 +08:00
|
|
|
</ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
It creates a connection to the specified database.
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
The <Replaceable>connection target</Replaceable> can be specified in the
|
|
|
|
following ways:
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>dbname[@server][:port][as <Replaceable>connection name</Replaceable>][user <Replaceable>user name</Replaceable>]</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>tcp:postgresql://server[:port][/dbname][as <Replaceable>connection name</Replaceable>][user <Replaceable>user name</Replaceable>]</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>unix:postgresql://server[:port][/dbname][as <Replaceable>connection name</Replaceable>][user <Replaceable>user name</Replaceable>]</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>character variable</Replaceable>[as <Replaceable>connection name</Replaceable>][user <Replaceable>user name</Replaceable>]</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>character string</Replaceable>[as <Replaceable>connection name</Replaceable>][<Replaceable>user</Replaceable>]</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>default</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>user</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
There are also different ways to specify the user name:
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>userid</Replaceable></Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>userid</Replaceable>/<Replaceable>password</Replaceable></Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>userid</Replaceable> identified by <Replaceable>password</Replaceable></Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>userid</Replaceable> using <Replaceable>password</Replaceable></Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para> Finally the userid and the password. Each may be a constant text, a
|
|
|
|
character variable or a chararcter string.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Disconnect statements</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
A disconnect statement looks loke:
|
1998-03-01 16:16:16 +08:00
|
|
|
<ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
exec sql disconnect [<Replaceable>connection target</Replaceable>];
|
1998-03-01 16:16:16 +08:00
|
|
|
</ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
It closes the connection to the specified database.
|
|
|
|
</Para>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
The <Replaceable>connection target</Replaceable> can be specified in the
|
|
|
|
following ways:
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term><Replaceable>connection name</Replaceable></Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>default</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>current</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>all</Term>
|
1999-03-30 23:20:43 +08:00
|
|
|
<listitem><para></para></listitem>
|
1999-03-24 22:54:10 +08:00
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
1999-03-30 23:20:43 +08:00
|
|
|
<!--WARNING: FROM HERE ON THE TEXT IS OUTDATED!-->
|
1998-03-01 16:16:16 +08:00
|
|
|
<VarListEntry>
|
|
|
|
<Term>Open cursor statement</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
An open cursor statement looks like:
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql open <Replaceable>cursor</Replaceable>;
|
|
|
|
</ProgramListing>
|
|
|
|
and is ignore and not copied from the output.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Commit statement</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
A commit statement looks like
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql commit;
|
|
|
|
</ProgramListing>
|
|
|
|
and is translated on the output to
|
|
|
|
<ProgramListing>
|
|
|
|
ECPGcommit(__LINE__);
|
|
|
|
</ProgramListing>
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Rollback statement</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
A rollback statement looks like
|
|
|
|
<ProgramListing>
|
|
|
|
exec sql rollback;
|
|
|
|
</ProgramListing>
|
|
|
|
and is translated on the output to
|
|
|
|
<ProgramListing>
|
|
|
|
ECPGrollback(__LINE__);
|
|
|
|
</ProgramListing>
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
1999-03-30 23:20:43 +08:00
|
|
|
<!--STARTING HERE IT IS OKAY AGAIN!-->
|
1998-03-01 16:16:16 +08:00
|
|
|
<VarListEntry>
|
|
|
|
<Term>Other statements</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
Other <Acronym>SQL</Acronym> statements are other statements that start with
|
1998-10-11 01:12:18 +08:00
|
|
|
<Command>exec sql</Command> and ends with <Command>;</Command>.
|
|
|
|
Everything inbetween is treated
|
1998-03-01 16:16:16 +08:00
|
|
|
as an <Acronym>SQL</Acronym> statement and parsed for variable substitution.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
Variable substitution occur when a symbol starts with a colon
|
1999-03-24 22:54:10 +08:00
|
|
|
(<Command>:</Command>). Then a variable with that name is looked for among
|
|
|
|
the variables that were previously declared within a declare section and
|
|
|
|
depending on the variable being for input or output the pointers to the
|
|
|
|
variables are written to the output to allow for access by the function.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
For every variable that is part of the <Acronym>SQL</Acronym> request
|
1999-03-24 22:54:10 +08:00
|
|
|
the function gets another ten arguments:
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<SimpleList>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Member>The type as a special symbol.</Member>
|
|
|
|
<Member>A pointer to the value or a pointer to the pointer.</Member>
|
|
|
|
<Member>The size of the variable if it is a char or varchar.</Member>
|
|
|
|
<Member>Number of elements in the array (for array fetches).</Member>
|
1998-03-01 16:16:16 +08:00
|
|
|
<Member>The offset to the next element in the array (for array fetches)</Member>
|
1999-03-24 22:54:10 +08:00
|
|
|
<Member>The type of the indicator variable as a special symbol.</Member>
|
|
|
|
<Member>A pointer to the value of the indicator variable or a pointer to the pointer of the indicator variable.</Member>
|
|
|
|
<Member>0.</Member>
|
|
|
|
<Member>Number of elements in the indicator array (for array fetches).</Member>
|
|
|
|
<Member>The offset to the next element in the indicator array (for array fetches)</Member>
|
1998-03-01 16:16:16 +08:00
|
|
|
</SimpleList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
</Sect2>
|
|
|
|
|
|
|
|
<Sect2>
|
|
|
|
<Title>A Complete Example</Title>
|
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
Here is a complete example describing the output of the preprocessor of a
|
|
|
|
file foo.pgc:
|
1998-03-01 16:16:16 +08:00
|
|
|
<ProgramListing>
|
|
|
|
exec sql begin declare section;
|
|
|
|
int index;
|
|
|
|
int result;
|
|
|
|
exec sql end declare section;
|
|
|
|
...
|
1999-03-24 22:54:10 +08:00
|
|
|
exec sql select res into :result from mytable where index = :index;
|
1998-03-01 16:16:16 +08:00
|
|
|
</ProgramListing>
|
|
|
|
is translated into:
|
|
|
|
<ProgramListing>
|
1999-03-24 22:54:10 +08:00
|
|
|
/* Processed by ecpg (2.6.0) */
|
1998-03-01 16:16:16 +08:00
|
|
|
/* These two include files are added by the preprocessor */
|
1999-03-24 22:54:10 +08:00
|
|
|
#include <ecpgtype.h>;
|
|
|
|
#include <ecpglib.h>;
|
|
|
|
|
1998-03-01 16:16:16 +08:00
|
|
|
/* exec sql begin declare section */
|
|
|
|
|
1999-03-24 22:54:10 +08:00
|
|
|
#line 1 "foo.pgc"
|
|
|
|
|
1998-03-01 16:16:16 +08:00
|
|
|
int index;
|
|
|
|
int result;
|
|
|
|
/* exec sql end declare section */
|
|
|
|
...
|
1999-03-24 22:54:10 +08:00
|
|
|
ECPGdo(__LINE__, NULL, "select res from mytable where index = ? ",
|
|
|
|
ECPGt_int,&(index),1L,1L,sizeof(int),
|
|
|
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EOIT,
|
|
|
|
ECPGt_int,&(result),1L,1L,sizeof(int),
|
|
|
|
ECPGt_NO_INDICATOR, NULL , 0L, 0L, 0L, ECPGt_EORT);
|
|
|
|
#line 147 "foo.pgc"
|
|
|
|
|
1998-03-01 16:16:16 +08:00
|
|
|
</ProgramListing>
|
|
|
|
(the indentation in this manual is added for readability and not
|
|
|
|
something that the preprocessor can do.)
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect2>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Sect2>
|
|
|
|
<Title>The Library</Title>
|
|
|
|
|
|
|
|
<Para>
|
|
|
|
The most important function in the library is the <Function>ECPGdo</Function>
|
1999-03-24 22:54:10 +08:00
|
|
|
function. It takes a variable amount of arguments. Hopefully we will not run
|
1998-03-01 16:16:16 +08:00
|
|
|
into machines with limits on the amount of variables that can be
|
1999-03-24 22:54:10 +08:00
|
|
|
accepted by a vararg function. This could easily add up to 50 or so
|
1998-03-01 16:16:16 +08:00
|
|
|
arguments.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
The arguments are:
|
|
|
|
|
|
|
|
<VariableList>
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>A line number</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
This is a line number for the original line used in error messages only.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>A string</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
1998-10-11 01:12:18 +08:00
|
|
|
This is the <Acronym>SQL</Acronym> request that is to be issued.
|
|
|
|
This request is modified
|
1998-03-01 16:16:16 +08:00
|
|
|
by the input variables, i.e. the variables that where not known at
|
|
|
|
compile time but are to be entered in the request. Where the variables
|
|
|
|
should go the string contains <Quote>;</Quote>.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Input variables</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
As described in the section about the preprocessor every input variable
|
1999-03-24 22:54:10 +08:00
|
|
|
gets ten arguments.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>ECPGt_EOIT</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
An enum telling that there are no more input variables.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>Output variables</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
As described in the section about the preprocessor every input variable
|
1999-03-24 22:54:10 +08:00
|
|
|
gets ten arguments. These variables are filled by the function.
|
1998-03-01 16:16:16 +08:00
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
|
|
|
|
<VarListEntry>
|
|
|
|
<Term>ECPGt_EORT</Term>
|
|
|
|
<ListItem>
|
|
|
|
<Para>
|
|
|
|
An enum telling that there are no more variables.
|
|
|
|
</Para>
|
|
|
|
</ListItem>
|
|
|
|
</VarListEntry>
|
|
|
|
</VariableList>
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
1999-03-24 22:54:10 +08:00
|
|
|
All the <Acronym>SQL</Acronym> statements are performed in one transaction
|
|
|
|
unless you issue a commit transaction. To get this auto-transaction going
|
|
|
|
the first statement or the first after statement after a commit or rollback
|
|
|
|
always begins a transaction. To disable this feature per default use the
|
|
|
|
'-t' option on the commandline
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
1998-03-01 16:16:16 +08:00
|
|
|
|
|
|
|
<Para>
|
|
|
|
To be completed: entries describing the other entries.
|
1998-12-29 10:24:47 +08:00
|
|
|
</Para>
|
|
|
|
</sect2>
|
|
|
|
</sect1>
|
1998-03-01 16:16:16 +08:00
|
|
|
</Chapter>
|