📄 ecpg.sgml
字号:
<!--$PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.71 2005/11/04 23:13:59 petere Exp $--><chapter id="ecpg"> <title><application>ECPG</application> - Embedded <acronym>SQL</acronym> in C</title> <indexterm zone="ecpg"><primary>embedded SQL</primary><secondary>in C</secondary></indexterm> <indexterm zone="ecpg"><primary>C</primary></indexterm> <indexterm zone="ecpg"><primary>ECPG</primary></indexterm> <para> This chapter describes the embedded <acronym>SQL</acronym> package for <productname>PostgreSQL</productname>. It was written by Linus Tolke (<email>linus@epact.se</email>) and Michael Meskes (<email>meskes@postgresql.org</email>). Originally it was written to work with <acronym>C</acronym>. It also works with <acronym>C++</acronym>, but it does not recognize all <acronym>C++</acronym> constructs yet. </para> <para> This documentation is quite incomplete. But since this interface is standardized, additional information can be found in many resources about SQL. </para> <sect1 id="ecpg-concept"> <title>The Concept</title> <para> An embedded SQL program consists of code written in an ordinary programming language, in this case C, mixed with SQL commands in specially marked sections. To build the program, the source code is first passed through the embedded SQL preprocessor, which converts it to an ordinary C program, and afterwards it can be processed by a C compiler. </para> <para> Embedded <acronym>SQL</acronym> has advantages over other methods for handling <acronym>SQL</acronym> commands from C code. First, it takes care of the tedious passing of information to and from variables in your <acronym>C</acronym> program. Second, the SQL code in the program is checked at build time for syntactical correctness. Third, embedded <acronym>SQL</acronym> in C is specified in the <acronym>SQL</acronym> standard and supported by many other <acronym>SQL</acronym> database systems. The <productname>PostgreSQL</> implementation is designed to match this standard as much as possible, and it is usually possible to port embedded <acronym>SQL</acronym> programs written for other SQL databases to <productname>PostgreSQL</productname> with relative ease. </para> <para> As already stated, programs written for the embedded <acronym>SQL</acronym> interface are normal C programs with special code inserted to perform database-related actions. This special code always has the form<programlisting>EXEC SQL ...;</programlisting> These statements syntactically take the place of a C statement. Depending on the particular statement, they may appear at the global level or within a function. Embedded <acronym>SQL</acronym> statements follow the case-sensitivity rules of normal <acronym>SQL</acronym> code, and not those of C. </para> <para> The following sections explain all the embedded SQL statements. </para> </sect1> <sect1 id="ecpg-connect"> <title>Connecting to the Database Server</title> <para> One connects to a database using the following statement:<programlisting>EXEC SQL CONNECT TO <replaceable>target</replaceable> <optional>AS <replaceable>connection-name</replaceable></optional> <optional>USER <replaceable>user-name</replaceable></optional>;</programlisting> The <replaceable>target</replaceable> can be specified in the following ways: <itemizedlist> <listitem> <simpara> <literal><replaceable>dbname</><optional>@<replaceable>hostname</></optional><optional>:<replaceable>port</></optional></literal> </simpara> </listitem> <listitem> <simpara> <literal>tcp:postgresql://<replaceable>hostname</><optional>:<replaceable>port</></optional><optional>/<replaceable>dbname</></optional><optional>?<replaceable>options</></optional></literal> </simpara> </listitem> <listitem> <simpara> <literal>unix:postgresql://<replaceable>hostname</><optional>:<replaceable>port</></optional><optional>/<replaceable>dbname</></optional><optional>?<replaceable>options</></optional></literal> </simpara> </listitem> <listitem> <simpara> an SQL string literal containing one of the above forms </simpara> </listitem> <listitem> <simpara> a reference to a character variable containing one of the above forms (see examples) </simpara> </listitem> <listitem> <simpara> <literal>DEFAULT</literal> </simpara> </listitem> </itemizedlist> If you specify the connection target literally (that is, not through a variable reference) and you don't quote the value, then the case-insensitivity rules of normal SQL are applied. In that case you can also double-quote the individual parameters separately as needed. In practice, it is probably less error-prone to use a (single-quoted) string literal or a variable reference. The connection target <literal>DEFAULT</literal> initiates a connection to the default database under the default user name. No separate user name or connection name may be specified in that case. </para> <para> There are also different ways to specify the user name: <itemizedlist> <listitem> <simpara> <literal><replaceable>username</replaceable></literal> </simpara> </listitem> <listitem> <simpara> <literal><replaceable>username</replaceable>/<replaceable>password</replaceable></literal> </simpara> </listitem> <listitem> <simpara> <literal><replaceable>username</replaceable> IDENTIFIED BY <replaceable>password</replaceable></literal> </simpara> </listitem> <listitem> <simpara> <literal><replaceable>username</replaceable> USING <replaceable>password</replaceable></literal> </simpara> </listitem> </itemizedlist> As above, the parameters <replaceable>username</replaceable> and <replaceable>password</replaceable> may be an SQL identifier, an SQL string literal, or a reference to a character variable. </para> <para> The <replaceable>connection-name</replaceable> is used to handle multiple connections in one program. It can be omitted if a program uses only one connection. The most recently opened connection becomes the current connection, which is used by default when an SQL statement is to be executed (see later in this chapter). </para> <para> Here are some examples of <command>CONNECT</command> statements:<programlisting>EXEC SQL CONNECT TO mydb@sql.mydomain.com;EXEC SQL CONNECT TO 'unix:postgresql://sql.mydomain.com/mydb' AS myconnection USER john;EXEC SQL BEGIN DECLARE SECTION;const char *target = "mydb@sql.mydomain.com";const char *user = "john";EXEC SQL END DECLARE SECTION; ...EXEC SQL CONNECT TO :target USER :user;</programlisting> The last form makes use of the variant referred to above as character variable reference. You will see in later sections how C variables can be used in SQL statements when you prefix them with a colon. </para> <para> Be advised that the format of the connection target is not specified in the SQL standard. So if you want to develop portable applications, you might want to use something based on the last example above to encapsulate the connection target string somewhere. </para> </sect1> <sect1 id="ecpg-disconnect"> <title>Closing a Connection</title> <para> To close a connection, use the following statement:<programlisting>EXEC SQL DISCONNECT <optional><replaceable>connection</replaceable></optional>;</programlisting> The <replaceable>connection</replaceable> can be specified in the following ways: <itemizedlist> <listitem> <simpara> <literal><replaceable>connection-name</replaceable></literal> </simpara> </listitem> <listitem> <simpara> <literal>DEFAULT</literal> </simpara> </listitem> <listitem> <simpara> <literal>CURRENT</literal> </simpara> </listitem> <listitem> <simpara> <literal>ALL</literal> </simpara> </listitem> </itemizedlist> If no connection name is specified, the current connection is closed. </para> <para> It is good style that an application always explicitly disconnect from every connection it opened. </para> </sect1> <sect1 id="ecpg-commands"> <title>Running SQL Commands</title> <para> Any SQL command can be run from within an embedded SQL application. Below are some examples of how to do that. </para> <para> Creating a table:<programlisting>EXEC SQL CREATE TABLE foo (number integer, ascii char(16));EXEC SQL CREATE UNIQUE INDEX num1 ON foo(number);EXEC SQL COMMIT;</programlisting> </para> <para> Inserting rows:<programlisting>EXEC SQL INSERT INTO foo (number, ascii) VALUES (9999, 'doodad');EXEC SQL COMMIT;</programlisting> </para> <para> Deleting rows:<programlisting>EXEC SQL DELETE FROM foo WHERE number = 9999;EXEC SQL COMMIT;</programlisting> </para> <para> Single-row select:<programlisting>EXEC SQL SELECT foo INTO :FooBar FROM table1 WHERE ascii = 'doodad';</programlisting> </para> <para> Select using cursors:<programlisting>EXEC SQL DECLARE foo_bar CURSOR FOR SELECT number, ascii FROM foo ORDER BY ascii;EXEC SQL OPEN foo_bar;EXEC SQL FETCH foo_bar INTO :FooBar, DooDad;...EXEC SQL CLOSE foo_bar;EXEC SQL COMMIT;</programlisting> </para> <para> Updates:<programlisting>EXEC SQL UPDATE foo SET ascii = 'foobar' WHERE number = 9999;EXEC SQL COMMIT;</programlisting> </para> <para> The tokens of the form <literal>:<replaceable>something</replaceable></literal> are <firstterm>host variables</firstterm>, that is, they refer to variables in the C program. They are explained in <xref linkend="ecpg-variables">. </para> <para> In the default mode, statements are committed only when <command>EXEC SQL COMMIT</command> is issued. The embedded SQL interface also supports autocommit of transactions (similar to <application>libpq</> behavior) via the <option>-t</option> command-line option to <command>ecpg</command> (see below) or via the <literal>EXEC SQL SET AUTOCOMMIT TO ON</literal> statement. In autocommit mode, each command is automatically committed unless it is inside an explicit transaction block. This mode can be explicitly turned off using <literal>EXEC SQL SET AUTOCOMMIT TO OFF</literal>. </para> </sect1> <sect1 id="ecpg-set-connection"> <title>Choosing a Connection</title> <para> The SQL statements shown in the previous section are executed on the current connection, that is, the most recently opened one. If an application needs to manage multiple connections, then there are two ways to handle this. </para> <para> The first option is to explicitly choose a connection for each SQL statement, for example<programlisting>EXEC SQL AT <replaceable>connection-name</replaceable> SELECT ...;</programlisting> This option is particularly suitable if the application needs to use several connections in mixed order. </para> <para> If your application uses multiple threads of execution, they cannot share a connection concurrently. You must either explicitly control access to the connection (using mutexes) or use a connection for each thread. If each thread uses its own connection, you will need to use the AT clause to specify which connection the thread will use. </para> <para> The second option is to execute a statement to switch the current connection. That statement is:<programlisting>EXEC SQL SET CONNECTION <replaceable>connection-name</replaceable>;</programlisting> This option is particularly convenient if many statements are to be executed on the same connection. It is not thread-aware. </para> </sect1> <sect1 id="ecpg-variables"> <title>Using Host Variables</title> <para> In <xref linkend="ecpg-commands"> you saw how you can execute SQL statements from an embedded SQL program. Some of those statements only used fixed values and did not provide a way to insert user-supplied values into statements or have the program process the values returned by the query. Those kinds of statements are not really useful in real applications. This section explains in detail how you can pass data between your C program and the embedded SQL statements using a simple mechanism called <firstterm>host variables</firstterm>. </para> <sect2> <title>Overview</title> <para> Passing data between the C program and the SQL statements is particularly simple in embedded SQL. Instead of having the program paste the data into the statement, which entails various complications, such as properly quoting the value, you can simply write the name of a C variable into the SQL statement, prefixed by a colon. For example:<programlisting>EXEC SQL INSERT INTO sometable VALUES (:v1, 'foo', :v2);</programlisting> This statements refers to two C variables named <varname>v1</varname> and <varname>v2</varname> and also uses a regular SQL string literal, to illustrate that you are not restricted to use one kind of data or the other. </para> <para> This style of inserting C variables in SQL statements works anywhere a value expression is expected in an SQL statement. In the SQL environment we call the references to C variables <firstterm>host variables</firstterm>. </para> </sect2> <sect2> <title>Declare Sections</title> <para> To pass data from the program to the database, for example as parameters in a query, or to pass data from the database back to the program, the C variables that are intended to contain this data need to be declared in specially marked sections, so the embedded SQL preprocessor is made aware of them. </para> <para> This section starts with<programlisting>EXEC SQL BEGIN DECLARE SECTION;</programlisting> and ends with<programlisting>EXEC SQL END DECLARE SECTION;</programlisting> Between those lines, there must be normal C variable declarations, such as<programlisting>int x;char foo[16], bar[16];</programlisting> You can have as many declare sections in a program as you like. </para> <para> The declarations are also echoed to the output file as normal C variables, so there's no need to declare them again. Variables that are not intended to be used in SQL commands can be declared normally outside these special sections. </para> <para> The definition of a structure or union also must be listed inside a <literal>DECLARE</> section. Otherwise the preprocessor cannot handle these types since it does not know the definition. </para> <para> The special type <type>VARCHAR</type> is converted into a named <type>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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -