PostgreSQL 管理數(shù)據(jù)庫(kù)連接

2021-09-02 14:06 更新
35.2.1. 連接到數(shù)據(jù)庫(kù)服務(wù)器
35.2.2. 選擇一個(gè)連接
35.2.3. 關(guān)閉一個(gè)連接

這一節(jié)描述如何打開、關(guān)閉以及切換數(shù)據(jù)庫(kù)連接。

35.2.1. 連接到數(shù)據(jù)庫(kù)服務(wù)器

我們可以使用下列語(yǔ)句連接到一個(gè)數(shù)據(jù)庫(kù):

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]
  • 一個(gè)包含上述形式之一的 SQL 字符串
  • 到一個(gè)包含上述形式之一(參見例子)的字符變量的引用
  • DEFAULT

如果你用字面(也就是不通過一個(gè)變量引用)指定連接目標(biāo)并且你沒有引用該值,那么將會(huì)應(yīng)用普通 SQL 的大小寫不敏感性規(guī)則。在那種情況中,你也能夠按照需要單獨(dú)將個(gè)體參數(shù)放置在雙引號(hào)中。實(shí)際上,使用一個(gè)(單引號(hào)引用)的字符串或一個(gè)變量引用出錯(cuò)的可能性更小。連接目標(biāo)DEFAULT會(huì)以默認(rèn)用戶名發(fā)起一個(gè)到默認(rèn)數(shù)據(jù)庫(kù)的連接。在那種情況中不能指定單獨(dú)的用戶名或連接名。

也有不同的方法來指定用戶名:

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

如上所述,參數(shù)username以及password可以是一個(gè) SQL 標(biāo)識(shí)符、一個(gè) SQL 字符串或者一個(gè)對(duì)字符變量的引用。

如果連接目標(biāo)包含任何options, 這些由keyword =value 組成的規(guī)范,由表示“和”的符號(hào)(&)分隔。 允許的關(guān)鍵字與libpq識(shí)別的關(guān)鍵字相同(參見第 33.1.2 節(jié))。 在任何keywordvalue 之前的空格將被忽略,但其中或之后則不會(huì)。 請(qǐng)注意,無法將&寫入value

connection-name被用來在一個(gè)程序中處理多個(gè)連接。如果一個(gè)程序只使用一個(gè)連接,它可以被忽略。最近被打開的連接將成為當(dāng)前連接,當(dāng)一個(gè) SQL 語(yǔ)句要被執(zhí)行時(shí),將默認(rèn)使用它(見這一章稍后的部分)。

如果不可信用戶能夠訪問一個(gè)沒有采用安全方案使用模式的數(shù)據(jù)庫(kù),開始每個(gè)會(huì)話時(shí)應(yīng)該從search_path中移除公共可寫的方案。 例如,把options=-c search_path=加到options 中或者在連接后發(fā)出EXEC SQL SELECT pg_catalog.set_config('search_path', '',false);。 這種考慮并非專門針對(duì)ECPG,它適用于每一種用來執(zhí)行任意SQL命令的接口。

這里有一些CONNECT語(yǔ)句的例子:

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

最后一種形式利用被上文成為字符變量引用的變體。你將在后面的小節(jié)中看到當(dāng)你把 C 變量前放上一個(gè)冒號(hào)時(shí),它們是怎樣被用于 SQL 語(yǔ)句的。

注意連接目標(biāo)的格式?jīng)]有在 SQL 標(biāo)準(zhǔn)中說明。因此如果你想要開發(fā)可移植的應(yīng)用,你可能想要使用某種基于上述最后一個(gè)例子的方法來把連接目標(biāo)字符串封裝在某個(gè)地方。

35.2.2. 選擇一個(gè)連接

嵌入式 SQL 程序中的 SQL 語(yǔ)句默認(rèn)是在當(dāng)前連接(也就是最近打開的那一個(gè))上執(zhí)行的。如果一個(gè)應(yīng)用需要管理多個(gè)連接,那么有兩種方法來處理這種需求。

第一個(gè)選項(xiàng)是顯式地為每一個(gè) SQL 語(yǔ)句選擇一個(gè)連接,例如:

EXEC SQL AT connection-name SELECT ...;

如果應(yīng)用需要以混合的順序使用多個(gè)連接,這個(gè)選項(xiàng)特別合適。

如果你的應(yīng)用使用多個(gè)線程執(zhí)行,它們不能并發(fā)地共享一個(gè)連接。你必須顯式地控制對(duì)連接的訪問(使用互斥量)或者為每個(gè)線程使用一個(gè)連接。

第二個(gè)選項(xiàng)是執(zhí)行一個(gè)語(yǔ)句來切換當(dāng)前的連接。該語(yǔ)句是:

EXEC SQL SET CONNECTION connection-name;

如果很多語(yǔ)句要被在同一個(gè)連接上執(zhí)行,這個(gè)選項(xiàng)特別方便。

這里有一個(gè)管理多個(gè)數(shù)據(jù)庫(kù)連接的例子程序:

#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;

    /* 這個(gè)查詢將在最近打開的數(shù)據(jù)庫(kù) "testdb3" 中執(zhí)行 */
    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb3)\n", dbname);

    /* 使用 "AT" 在 "testdb2" 中運(yùn)行一個(gè)查詢 */
    EXEC SQL AT con2 SELECT current_database() INTO :dbname;
    printf("current=%s (should be testdb2)\n", dbname);

    /* 切換當(dāng)前連接到 "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;
}

這個(gè)例子將產(chǎn)生這樣的輸出:

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

35.2.3. 關(guān)閉一個(gè)連接

要關(guān)閉一個(gè)連接,使用下列語(yǔ)句:

EXEC SQL DISCONNECT [connection];

connection可以用下列方法指定:

  • connection-name
  • DEFAULT
  • CURRENT
  • ALL

如果沒有指定連接名,當(dāng)前連接將被關(guān)閉。

在一個(gè)應(yīng)用中總是顯式地從它打開的每一個(gè)連接斷開是一種好的風(fēng)格。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)