35.2. Management 数据库连接

本节介绍如何打开,关闭和切换数据库连接。

35 .2.1. 连接到数据库服务器

使用以下语句连接到数据库:

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

可以通过以下方式指定* target *:

  • dbname[@hostname][:port]

  • tcp:postgresql://hostname[:port][/dbname][?options]

  • unix:postgresql://hostname[:port][/dbname][?options]

  • 包含上述形式之一的 SQL 字符串 Literals

  • 对包含上述形式之一的字符变量的引用(请参见示例)

  • DEFAULT

如果您按字面值指定连接目标(即,不是通过变量引用),并且没有引用该值,那么将应用普通 SQL 的不区分大小写规则。在这种情况下,您还可以根据需要将各个参数分别双引号。实际上,使用(单引号)字符串 Literals 或变量引用可能不太容易出错。连接目标DEFAULT以默认用户名启动到默认数据库的连接。在这种情况下,不能指定单独的用户名或连接名。

还有其他方法可以指定用户名:

  • username

  • username/password

  • username IDENTIFIED BY password

  • username USING password

如上所述,参数* username password *可以是 SQL 标识符,SQL 字符串 Literals 或对字符变量的引用。

如果连接目标包括任何* options ,则它们由keyword=value规范组成,并以&符(&)分隔。允许的关键字与 libpq 识别的关键字相同(请参阅Section 33.1.2)。在任何 keyword value 之前的空格都将被忽略,尽管不在一个空格内或之后。请注意,无法在 value *中写入&

  • connection-name *用于在一个程序中处理多个连接。如果程序仅使用一个连接,则可以省略。最近打开的连接成为当前连接,默认情况下将在执行 SQL 语句时使用该连接(请参阅本章稍后)。

如果不受信任的用户可以访问未采用安全模式使用模式的数据库,请通过从search_path删除可公开写模式来开始每个会话。例如,将options=-c search_path=添加到options,或在连接后发出EXEC SQL SELECT pg_catalog.set_config('search_path', '', false);。此注意事项并非仅针对 ECPG;它适用于执行任意 SQL 命令的每个接口。

以下是CONNECT语句的一些示例:

EXEC SQL CONNECT TO [email protected];

EXEC SQL CONNECT TO unix:postgresql://sql.mydomain.com/mydb AS myconnection USER john;

EXEC SQL BEGIN DECLARE SECTION;
const char *target = "[email protected]";
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; */

最后一种形式使用了上面称为字符变量引用的变体。在后面的部分中,您将看到在用冒号作为前缀的情况下如何在 SQL 语句中使用 C 变量。

建议不要在 SQL 标准中指定连接目标的格式。因此,如果您要开发可移植的应用程序,则可能需要根据上面的最后一个示例使用某些东西将连接目标字符串封装在某个位置。

35 .2.2. 选择连接

默认情况下,嵌入式 SQL 程序中的 SQL 语句在当前连接(即最近打开的连接)上执行。如果应用程序需要 Management 多个连接,则有两种方法可以处理此问题。

第一种选择是为每个 SQL 语句显式选择一个连接,例如:

EXEC SQL AT connection-name SELECT ...;

如果应用程序需要以混合 Sequences 使用多个连接,则此选项特别适用。

如果您的应用程序使用多个执行线程,则它们无法同时共享连接。您必须显式控制对连接的访问(使用互斥锁)或对每个线程使用连接。

第二个选项是执行一条语句以切换当前连接。该语句是:

EXEC SQL SET CONNECTION connection-name;

如果要在同一连接上执行许多语句,则此选项特别方便。

这是 Management 多个数据库连接的示例程序:

#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". */
    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb3)\n", dbname);

    /* Using "AT" to run a query in "testdb2" */
    EXEC SQL AT con2 SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb2)\n", dbname);

    /* Switch the current connection to "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;
}

此示例将产生以下输出:

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

35 .2.3. 断开连接

要关闭连接,请使用以下语句:

EXEC SQL DISCONNECT [connection];

可以通过以下方式指定* connection *:

  • connection-name

  • DEFAULT

  • CURRENT

  • ALL

如果未指定连接名称,则当前连接关闭。

良好的样式是应用程序始终显式断开其打开的每个连接。