バージョンごとのドキュメント一覧

36.2. データベース接続の管理 #

<title>Managing Database Connections</title>

This section describes how to open, close, and switch database connections. この節では、データベース接続の開始、終了、および切り替え方について解説します。

36.2.1. データベースサーバへの接続 #

<title>Connecting to the Database Server</title>

One connects to a database using the following statement: 以下のSQL文を使用して、データベースへ接続します。

EXEC SQL CONNECT TO target [AS connection-name] [USER user-name];

The <replaceable>target</replaceable> can be specified in the following ways: targetは以下の方法で指定されます。

  • dbname[@hostname][:port]
  • tcp:postgresql://hostname[:port][/dbname][?options]
  • unix:postgresql://localhost[:port][/dbname][?options]
  • an SQL string literal containing one of the above forms 上の形式のいずれかを含むSQL文字列リテラル。
  • a reference to a character variable containing one of the above forms (see examples) 上の形式のいずれかを含む文字変数への参照。
  • DEFAULT

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 can be specified in that case. DEFAULT接続対象は、デフォルトデータベース、デフォルトのユーザ名で接続を初期化します。 この場合は、ユーザ名と接続名を分けて指定することができません。

If you specify the connection target directly (that is, not as a string literal or variable reference), then the components of the target are passed through normal SQL parsing; this means that, for example, the <replaceable>hostname</replaceable> must look like one or more SQL identifiers separated by dots, and those identifiers will be case-folded unless double-quoted. Values of any <replaceable>options</replaceable> must be SQL identifiers, integers, or variable references. Of course, you can put nearly anything into an SQL identifier by double-quoting it. In practice, it is probably less error-prone to use a (single-quoted) string literal or a variable reference than to write the connection target directly. 接続対象を直接(すなわち、文字列リテラルとしてでも、変数参照でもない形で)指定した場合、対象の要素は通常のSQLとして解析されて渡されます。これは、例えば、hostnameはドットで区切られた一つ以上のSQL識別子のようでなければならなず、識別子が二重引用符で括られていなければ大文字小文字は区別されないということを意味します。 optionsの値は、SQL識別子、整数、もしくは変数参照でなければなりません。 もちろん、二重引用符で括ることでSQL識別子の中にほぼ何でも入れることができます。 実際には、おそらく(単一引用符でくくられた)文字列リテラルもしくは変数の参照を使用した方がエラーをより防止できます。

There are also different ways to specify the user name: ユーザ名を指定するには、別の方法もあります。

  • username
  • username/password
  • username IDENTIFIED BY password
  • username USING password

As above, the parameters <replaceable>username</replaceable> and <replaceable>password</replaceable> can be an SQL identifier, an SQL string literal, or a reference to a character variable. これまで同様、usernamepasswordは、SQL識別子、SQL文字列リテラル、文字型変数への参照を取ることができます。

If the connection target includes any <replaceable>options</replaceable>, those consist of <literal><replaceable>keyword</replaceable>=<replaceable>value</replaceable></literal> specifications separated by ampersands (<literal>&amp;</literal>). The allowed key words are the same ones recognized by <application>libpq</application> (see <xref linkend="libpq-paramkeywords"/>). Spaces are ignored before any <replaceable>keyword</replaceable> or <replaceable>value</replaceable>, though not within or after one. Note that there is no way to write <literal>&amp;</literal> within a <replaceable>value</replaceable>. 接続対象にoptionsを含めるのなら、keyword=value指定をアンパサンド(&)で区切って構成します。 許されるキーワードは、libpqが認識するものと同じです(34.1.2を参照してください)。 keywordvalueの前の空白は無視されますが、中や後の空白は無視されません。 valueの中に&を書く方法はないことに注意してください。

Notice that when specifying a socket connection (with the <literal>unix:</literal> prefix), the host name must be exactly <literal>localhost</literal>. To select a non-default socket directory, write the directory's pathname as the value of a <varname>host</varname> option in the <replaceable>options</replaceable> part of the target. (unix:接頭辞で)ソケット接続を指定するときには、ホスト名は厳密にlocalhostでなければなりません。 デフォルトでないソケットディレクトリを選ぶためには、対象のoptions部分のhostオプションの値としてディレクトリのパス名を書いてください。

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). 1つのプログラム内で複数の接続を処理する場合には、connection-nameを使用します。 プログラムで1つしか接続を使わない場合は省略して構いません。 最も最近に開かれた接続が現在の接続になり、SQL文を実行しようとする時にデフォルトでこの接続が使用されます(本章の後で説明します)。

Here are some examples of <command>CONNECT</command> statements: 以下にCONNECT文について、数例を示します。

EXEC SQL CONNECT TO mydb@sql.mydomain.com;

EXEC SQL CONNECT TO tcp: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";
const char *passwd = "secret";
EXEC SQL END DECLARE SECTION;
 ...
EXEC SQL CONNECT TO :target USER :user USING :passwd;

/* or EXEC SQL CONNECT TO :target USER :user/:passwd; */

/* もしくは EXEC SQL CONNECT TO :target USER :user/:passwd; */

The last example makes use of the feature referred to above as character variable references. You will see in later sections how C variables can be used in SQL statements when you prefix them with a colon. 最後の例では、文字変数参照として上を参照する機能を使用しています。 後の節で、接頭辞にコロンを持つ場合のSQL文内でのC変数の使用方法について説明します。

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. 接続対象の書式は標準SQLでは規定されていないことに注意してください。 そのため、移植可能なアプリケーションを開発したいのであれば、上の例の最後の方法を基にして、接続対象文字列をどこかにカプセル化してください。

If untrusted users have access to a database that has not adopted a <link linkend="ddl-schemas-patterns">secure schema usage pattern</link>, begin each session by removing publicly-writable schemas from <varname>search_path</varname>. For example, add <literal>options=-c search_path=</literal> to <literal><replaceable>options</replaceable></literal>, or issue <literal>EXEC SQL SELECT pg_catalog.set_config('search_path', '', false);</literal> after connecting. This consideration is not specific to ECPG; it applies to every interface for executing arbitrary SQL commands. 信用できないユーザが安全なスキーマ使用パターンを採用していないデータベースにアクセスできる場合、各セッションをsearch_pathから一般のユーザが書き込み可能なスキーマを取り除くことから始めます。 例えば、options=-c search_path=optionsに追加したり、接続後にEXEC SQL SELECT pg_catalog.set_config('search_path', '', false);を発行したりします。 この配慮はECPGに特有のものではありません。任意のSQLコマンドを実行するインタフェースすべてに当てはまります。

36.2.2. 接続の選択 #

<title>Choosing a Connection</title>

SQL statements in embedded SQL programs are by default executed on the current connection, that is, the most recently opened one. If an application needs to manage multiple connections, then there are three ways to handle this. 前節で示したSQL文は現在の接続、つまり、最も最近に開いた接続上で実行されます。 複数の接続を管理する必要があるアプリケーションでは、これを処理する3つの方法があります。

The first option is to explicitly choose a connection for each SQL statement, for example: 1つ目の選択肢は、各SQL文で明示的に接続を選択することです。 以下に例を示します。

EXEC SQL AT connection-name SELECT ...;

This option is particularly suitable if the application needs to use several connections in mixed order. アプリケーションが複数の接続を不特定な順番で使用する必要がある場合、この選択肢は特に適しています。

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. アプリケーションの実行に複数スレッドを使用する場合、スレッド間で接続を同時に共有できません。 接続へのアクセスを(ミューテクスを使用して)明示的に制御するか、または各スレッド用の接続を使用するかを行わなければなりません。

The second option is to execute a statement to switch the current connection. That statement is: 2つ目の選択肢は、現在の接続を切り替えるSQL文を実行することです。 以下のSQL文です。

EXEC SQL SET CONNECTION connection-name;

This option is particularly convenient if many statements are to be executed on the same connection. 多くのSQL文を同一接続に対して使用する場合、この選択肢は特に便利です。

Here is an example program managing multiple database connections: 以下に複数のデータベースコネクションを管理しているプログラムの例を示します。

#include <stdio.h>

EXEC SQL BEGIN DECLARE SECTION;
    char dbname[1024];
EXEC SQL END DECLARE SECTION;

int
main()
{
    EXEC SQL CONNECT TO testdb1 AS con1 USER testuser;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
    EXEC SQL CONNECT TO testdb2 AS con2 USER testuser;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
    EXEC SQL CONNECT TO testdb3 AS con3 USER testuser;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;


    /* This query would be executed in the last opened database "testdb3". */

    /* この問い合わせは最後に開いたデータベース"testdb3"で実行される。 */
    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb3)\n", dbname);


    /* Using "AT" to run a query in "testdb2" */

    /* "testdb2"で問い合わせを実行するには"AT"を使う */
    EXEC SQL AT con2 SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb2)\n", dbname);


    /* Switch the current connection to "testdb1". */

    /* 現在の接続を"testdb1"に切り替える。 */
    EXEC SQL SET CONNECTION con1;

    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb1)\n", dbname);

    EXEC SQL DISCONNECT ALL;
    return 0;
}

This example would produce this output: この例は、次のような出力を生成します。

current=testdb3 (should be testdb3)
current=testdb2 (should be testdb2)
current=testdb1 (should be testdb1)

The third option is to declare an SQL identifier linked to the connection, for example: 3つ目の選択肢は、接続に結び付いたSQL識別子を宣言することです。

EXEC SQL AT connection-name DECLARE statement-name STATEMENT;
EXEC SQL PREPARE statement-name FROM :dyn-string;

Once you link an SQL identifier to a connection, you execute dynamic SQL without an AT clause. Note that this option behaves like preprocessor directives, therefore the link is enabled only in the file. 一度SQL識別子を接続に結び付ければ、AT句なしに動的なSQLを実行できます。 この選択肢はプリプロセッサ指示子のように振る舞いますので、結び付けはファイルの中でのみ可能です。

Here is an example program using this option: 以下にこの選択肢を使用したプログラムの例を示します。

#include <stdio.h>

EXEC SQL BEGIN DECLARE SECTION;
char dbname[128];
char *dyn_sql = "SELECT current_database()";
EXEC SQL END DECLARE SECTION;

int main(){
  EXEC SQL CONNECT TO postgres AS con1;
  EXEC SQL CONNECT TO testdb AS con2;
  EXEC SQL AT con1 DECLARE stmt STATEMENT;
  EXEC SQL PREPARE stmt FROM :dyn_sql;
  EXEC SQL EXECUTE stmt INTO :dbname;
  printf("%s\n", dbname);

  EXEC SQL DISCONNECT ALL;
  return 0;
}

This example would produce this output, even if the default connection is testdb: この例は、たとえデフォルトの接続がtestdbであったとしても、次のような出力を生成します。

postgres

36.2.3. 接続を閉じる #

<title>Closing a Connection</title>

To close a connection, use the following statement: 接続を閉じるには以下のSQL文を使用します。

EXEC SQL DISCONNECT [connection];

The <replaceable>connection</replaceable> can be specified in the following ways: connectionは以下の方法で指定されます。

  • connection-name
  • DEFAULT
  • CURRENT
  • ALL

If no connection name is specified, the current connection is closed. 接続名の指定がなければ、現在の接続が閉じられます。

It is good style that an application always explicitly disconnect from every connection it opened. アプリケーションでは、過去に開いたすべての接続を明示的に閉じることを推奨します。