35.2. УпÑавление подклÑÑениÑми к базе даннÑÑ #
Ð ÑÑом Ñазделе опиÑÑваеÑÑÑ, как оÑкÑÑваÑÑ, закÑÑваÑÑ Ð¸ пеÑеклÑÑаÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ðº базам даннÑÑ .
35.2.1. ÐодклÑÑение к ÑеÑвеÑÑ Ð±Ð°Ð· даннÑÑ #
ÐодклÑÑение к базе даннÑÑ Ð²ÑполнÑеÑÑÑ ÑледÑÑÑим опеÑаÑоÑом:
EXEC SQL CONNECT TOÑелÑ-подклÑÑениÑ[ASимÑ-подклÑÑениÑ] [USERимÑ-полÑзоваÑелÑ];
Ð¦ÐµÐ»Ñ Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ ÑледÑÑÑими ÑпоÑобами:
dbname[@имÑ_ÑеÑвеÑа][:поÑÑ]tcp:postgresql://имÑ_ÑеÑвеÑа[:поÑÑ][/dbname][?паÑамеÑÑÑ]unix:postgresql://localhost[:поÑÑ][/dbname][?паÑамеÑÑÑ]- ÑÑÑÐ¾ÐºÐ¾Ð²Ð°Ñ ÐºÐ¾Ð½ÑÑанÑа SQL, ÑодеÑжаÑÐ°Ñ Ð¾Ð´Ð½Ñ Ð¸Ð· вÑÑепÑиведÑннÑÑ Ð·Ð°Ð¿Ð¸Ñей
- ÑÑÑлка на ÑимволÑнÑÑ Ð¿ÐµÑеменнÑÑ, ÑодеÑжаÑÑÑ Ð¾Ð´Ð½Ñ Ð¸Ð· вÑÑепÑиведÑннÑÑ Ð·Ð°Ð¿Ð¸Ñей (Ñм. пÑимеÑÑ)
DEFAULT
С ÑелÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ DEFAULT ÑÑÑанавливаеÑÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение к базе даннÑÑ
по ÑмолÑÐ°Ð½Ð¸Ñ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ полÑзоваÑÐµÐ»Ñ Ð¿Ð¾ ÑмолÑаниÑ. ÐÑÑгое Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð¸Ð»Ð¸ Ð¸Ð¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð² ÑÑом ÑлÑÑае ÑказаÑÑ Ð½ÐµÐ»ÑзÑ.
ÐÑли ÑÐµÐ»Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð·Ð°Ð´Ð°ÑÑÑÑ Ð±ÑквалÑно (не в виде ÑекÑÑовой ÑÑÑоки и не ÑеÑез пеÑеменнÑÑ), ÐµÑ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½ÑÑ ÑазбиÑаÑÑÑÑ ÐºÐ°Ðº обÑÑнÑе ÑлеменÑÑ SQL; ÑÑо ознаÑаеÑ, напÑимеÑ, ÑÑо имÑ_ÑеÑвеÑа должно вÑглÑдеÑÑ ÐºÐ°Ðº один или неÑколÑко иденÑиÑикаÑоÑов SQL, ÑазделÑннÑÑ
ÑоÑками, и еÑли они не заклÑÑÐµÐ½Ñ Ð² кавÑÑки, они бÑдÑÑ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ñ Ðº Ð½Ð¸Ð¶Ð½ÐµÐ¼Ñ ÑегиÑÑÑÑ. ÐнаÑÐµÐ½Ð¸Ñ Ð»ÑбÑÑ
паÑамеÑÑов Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑами SQL, ÑелÑми ÑиÑлами или ÑÑÑлками на пеÑеменнÑе. РазÑмееÑÑÑ, пÑакÑиÑеÑки лÑбÑÑ ÑÑÑÐ¾ÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑделаÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑом SQL, заклÑÑив ÐµÑ Ð² кавÑÑки. Ðа пÑакÑике же, во избежание оÑибок, пÑедпоÑÑиÑелÑнее иÑполÑзоваÑÑ ÑекÑÑовÑе ÑÑÑоки (в апоÑÑÑоÑаÑ
) или ÑÑÑлки на пеÑеменнÑе.
Также ÑазнÑми ÑпоÑобами можно ÑказаÑÑ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑелÑ:
имÑ_полÑзоваÑелÑимÑ_полÑзоваÑелÑ/паÑолÑимÑ_полÑзоваÑелÑIDENTIFIED BYпаÑолÑимÑ_полÑзоваÑелÑUSINGпаÑолÑ
РпоказаннÑÑ
вÑÑе ÑÑÑокаÑ
имÑ_полÑзоваÑÐµÐ»Ñ Ð¸ паÑÐ¾Ð»Ñ Ð¼Ð¾Ð³ÑÑ Ð·Ð°Ð´Ð°Ð²Ð°ÑÑÑÑ Ð¸Ð´ÐµÐ½ÑиÑикаÑоÑом или ÑÑÑоковой конÑÑанÑой SQL, либо ÑÑÑлкой на ÑимволÑнÑÑ Ð¿ÐµÑеменнÑÑ.
ÐÑли Ñказание Ñели подклÑÑÐµÐ½Ð¸Ñ Ð²ÐºÐ»ÑÑÐ°ÐµÑ ÐºÐ°ÐºÐ¸Ðµ-либо паÑамеÑÑÑ, они Ð´Ð¾Ð»Ð¶Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑваÑÑÑÑ Ð² виде и ÑазделÑÑÑÑÑ Ð°Ð¼Ð¿ÐµÑÑандами (имÑ=знаÑение&). РкаÑеÑÑве имÑн паÑамеÑÑов пÑинимаÑÑÑÑ Ñе же, ÑÑо поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ libpq (Ñм. ÐодÑаздел 33.1.2). ÐеÑед ÑлеменÑами Ð¸Ð¼Ñ Ð¸Ð»Ð¸ знаÑение пÑÐ¾Ð±ÐµÐ»Ñ Ð¸Ð³Ð½Ð¾ÑиÑÑÑÑÑÑ, но ÑоÑ
ÑанÑÑÑÑÑ Ð²Ð½ÑÑÑи или поÑле ÑÑиÑ
ÑлеменÑов. ÐамеÑÑÑе, ÑÑо запиÑаÑÑ & внÑÑÑи знаÑÐµÐ½Ð¸Ñ Ð½ÐµÑ Ð½Ð¸ÐºÐ°ÐºÐ¾Ð¹ возможноÑÑи.
ÐбÑаÑиÑе внимание, ÑÑо пÑи Ñказании ÑÐ¾ÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ ÑеÑез ÑÐ¾ÐºÐµÑ (Ñ Ð¿ÑеÑикÑом unix:) Ð¸Ð¼Ñ ÑеÑвеÑа обÑзаÑелÑно должно бÑÑÑ localhost. ЧÑÐ¾Ð±Ñ Ð²ÑбÑаÑÑ Ð½ÐµÑÑандаÑÑнÑй каÑалог ÑокеÑа, ÑкажиÑе пÑÑÑ Ðº каÑÐ°Ð»Ð¾Ð³Ñ ÐºÐ°Ðº знаÑение паÑамеÑÑа host в ÑпиÑке паÑамеÑÑов в ÑÑÑоке Ñели.
Указание имÑ-подклÑÑÐµÐ½Ð¸Ñ Ð¿ÑименÑеÑÑÑ, когда в одной пÑогÑамме нÑжно иÑполÑзоваÑÑ Ð½ÐµÑколÑко подклÑÑений. Ðго можно опÑÑÑиÑÑ, еÑли пÑогÑамма ÑабоÑÐ°ÐµÑ ÑолÑко Ñ Ð¾Ð´Ð½Ð¸Ð¼ подклÑÑением. Соединение, оÑкÑÑÑое поÑледним, ÑÑановиÑÑÑ ÑекÑÑим и бÑÐ´ÐµÑ Ð¸ÑполÑзоваÑÑÑÑ Ð¿Ð¾ ÑмолÑÐ°Ð½Ð¸Ñ Ð¿Ñи вÑполнении SQL-опеÑаÑоÑов (ÑÑо опиÑÑваеÑÑÑ Ð´Ð°Ð»ÐµÐµ в ÑÑой главе).
ÐÐ¾Ñ Ð½ÐµÐºÐ¾ÑоÑÑе пÑимеÑÑ Ð¾Ð¿ÐµÑаÑоÑа 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; */
РпоÑледней ÑоÑме иÑполÑзÑеÑÑÑ Ð²Ð°ÑианÑ, названнÑй вÑÑе ÑÑÑлкой на ÑимволÑнÑÑ Ð¿ÐµÑеменнÑÑ. РпоÑледÑÑÑÐ¸Ñ ÑÐ°Ð·Ð´ÐµÐ»Ð°Ñ Ð²Ñ ÑзнаеÑе, как в SQL-опеÑаÑоÑÐ°Ñ Ð¼Ð¾Ð¶Ð½Ð¾ иÑполÑзоваÑÑ Ð¿ÐµÑеменнÑе C, пÑиÑÑавлÑÑ Ð¿ÐµÑед именем двоеÑоÑие.
УÑÑиÑе, ÑÑо ÑоÑÐ¼Ð°Ñ Ñели подклÑÑÐµÐ½Ð¸Ñ Ð½Ðµ опиÑÑваеÑÑÑ Ð² ÑÑандаÑÑе SQL. ÐоÑÑомÑ, еÑли Ð²Ñ Ñ Ð¾ÑиÑе ÑазÑабаÑÑваÑÑ Ð¿ÐµÑеноÑимÑе пÑиложениÑ, Ð¸Ð¼ÐµÐµÑ ÑмÑÑл пÑимениÑÑ Ð¿Ð¾Ð´Ñ Ð¾Ð´, показаннÑй в поÑледнем пÑимеÑе, и ÑÑоÑмиÑоваÑÑ ÑÑÑÐ¾ÐºÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð¾ÑделÑно.
ÐÑли к базе даннÑÑ
, коÑоÑÐ°Ñ Ð½Ðµ пÑиведена в ÑооÑвеÑÑÑвие ÑÐ°Ð±Ð»Ð¾Ð½Ñ Ð±ÐµÐ·Ð¾Ð¿Ð°Ñного иÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑÑ
ем, имеÑÑ Ð´Ð¾ÑÑÑп недовеÑеннÑе полÑзоваÑели, наÑинайÑе ÑÐµÐ°Ð½Ñ Ñ ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ ÑÑ
ем, доÑÑÑпнÑÑ
вÑем Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи, из пÑÑи поиÑка (search_path). ÐапÑимеÑ, добавÑÑе options=-c search_path= в или вÑполниÑе optionsEXEC SQL SELECT pg_catalog.set_config('search_path', '', false); поÑле подклÑÑениÑ. ÐÑо каÑаеÑÑÑ Ð½Ðµ ÑолÑко ECPG, но и лÑбÑÑ
дÑÑгиÑ
инÑеÑÑейÑов Ð´Ð»Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿ÑоизволÑнÑÑ
SQL-команд.
35.2.2. ÐÑÐ±Ð¾Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ #
SQL-опеÑаÑоÑÑ Ð² пÑогÑÐ°Ð¼Ð¼Ð°Ñ Ñо вÑÑÑаиваемÑм SQL по ÑмолÑÐ°Ð½Ð¸Ñ Ð²ÑполнÑÑÑÑÑ Ñ ÑекÑÑим подклÑÑением, Ñо еÑÑÑ Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑением, коÑоÑое бÑло оÑкÑÑÑо поÑледним. ÐÑли пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ñжно ÑпÑавлÑÑÑ Ð½ÐµÑколÑкими подклÑÑениÑми, ÑÑо можно ÑделаÑÑ ÑÑÐµÐ¼Ñ ÑпоÑобами.
ÐеÑвÑй ваÑÐ¸Ð°Ð½Ñ â Ñвно вÑбиÑаÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ SQL-опеÑаÑоÑа, напÑимеÑ, Ñак:
EXEC SQL AT имÑ-подклÑÑÐµÐ½Ð¸Ñ SELECT ...;ÐÑÐ¾Ñ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ñ Ð¾ÑоÑо Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ ÑлÑÑаев, когда пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ñжно иÑполÑзоваÑÑ Ð½ÐµÑколÑко подклÑÑений в ÑмеÑанном поÑÑдке.
ÐÑли ваÑе пÑиложение вÑполнÑеÑÑÑ Ð² неÑколÑÐºÐ¸Ñ Ð¿Ð¾ÑÐ¾ÐºÐ°Ñ , они не могÑÑ Ð¸ÑполÑзоваÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение одновÑеменно. ÐоÑÑÐ¾Ð¼Ñ Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð»Ð¸Ð±Ð¾ Ñвно ÑпÑавлÑÑÑ Ð´Ð¾ÑÑÑпом (иÑполÑзÑÑ Ð¼ÑÑÑекÑÑ), либо иÑполÑзоваÑÑ Ð¾ÑделÑнÑе подклÑÑÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ поÑока.
ÐÑоÑой ваÑÐ¸Ð°Ð½Ñ â вÑполнÑÑÑ Ð¾Ð¿ÐµÑаÑоÑ, пеÑеклÑÑаÑÑий ÑекÑÑее подклÑÑение. ÐÑÐ¾Ñ Ð¾Ð¿ÐµÑаÑÐ¾Ñ Ð·Ð°Ð¿Ð¸ÑÑваеÑÑÑ Ñак:
EXEC SQL SET CONNECTION имÑ-подклÑÑениÑ;ÐÑÐ¾Ñ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð¾Ñобенно Ñдобен, когда Ñ Ð¾Ð´Ð½Ð¸Ð¼ подклÑÑением нÑжно вÑполниÑÑ Ð½ÐµÑколÑко опеÑаÑоÑов.
СледÑÑÑий пÑÐ¸Ð¼ÐµÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÐµÑ ÑпÑавление неÑколÑкими подклÑÑениÑми к базам даннÑÑ :
#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)
ТÑеÑий ваÑÐ¸Ð°Ð½Ñ Ð·Ð°ÐºÐ»ÑÑаеÑÑÑ Ð² обÑÑвлении иденÑиÑикаÑоÑа SQL, ÑвÑзанного Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑением. ÐапÑимеÑ:
EXEC SQL ATимÑ-подклÑÑениÑDECLAREимÑ-опеÑаÑоÑаSTATEMENT; EXEC SQL PREPAREимÑ-опеÑаÑоÑаFROM :динамиÑеÑкаÑ-ÑÑÑока;
СвÑзаннÑй Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑением SQL-иденÑиÑикаÑÐ¾Ñ Ð·Ð°Ñем нÑжно вÑполнÑÑÑ Ð±ÐµÐ· пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ AT. ÐбÑаÑиÑе внимание, ÑÑо ÑÑÐ¾Ñ Ð²Ð°ÑÐ¸Ð°Ð½Ñ Ð´ÐµÐ¹ÑÑвÑÐµÑ ÐºÐ°Ðº диÑекÑÐ¸Ð²Ñ Ð¿ÑепÑоÑеÑÑоÑа, поÑÑÐ¾Ð¼Ñ ÑÑо ÑвÑзÑвание бÑÐ´ÐµÑ ÑабоÑаÑÑ ÑолÑко в ÑÐ°Ð¼ÐºÐ°Ñ Ñайла.
СледÑÑÑий пÑÐ¸Ð¼ÐµÑ Ð¿ÑогÑÐ°Ð¼Ð¼Ñ Ð´ÐµÐ¼Ð¾Ð½ÑÑÑиÑÑÐµÑ Ð¸ÑполÑзование данного ваÑианÑа:
#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;
}
ÐÑÐ¾Ñ Ð¿ÑÐ¸Ð¼ÐµÑ Ð´Ð¾Ð»Ð¶ÐµÐ½ вÑвеÑÑи ÑледÑÑÑее, даже еÑли подклÑÑение по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑÑановлено к базе testdb:
postgres
35.2.3. ÐакÑÑÑие подклÑÑÐµÐ½Ð¸Ñ #
ЧÑÐ¾Ð±Ñ Ð·Ð°ÐºÑÑÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение, пÑимениÑе ÑледÑÑÑий опеÑаÑоÑ:
EXEC SQL DISCONNECT [подклÑÑение];ÐодклÑÑение можно задаÑÑ ÑледÑÑÑими ÑпоÑобами:
имÑ-подклÑÑениÑCURRENTALL
ÐÑли Ð¸Ð¼Ñ Ð¿Ð¾Ð´ÐºÐ»ÑÑÐµÐ½Ð¸Ñ Ð½Ðµ задано, закÑÑваеÑÑÑ ÑекÑÑее подклÑÑение.
ХоÑоÑим ÑÑилем ÑÑиÑаеÑÑÑ, когда пÑиложение Ñвно закÑÑÐ²Ð°ÐµÑ ÐºÐ°Ð¶Ð´Ð¾Ðµ подклÑÑение, коÑоÑое оно оÑкÑÑло.