DOC.PROTOTYPES.RU

Главная > Базы данных > PostgreSQL > Дополнения > dblink >
Имя

dblink_connect - функция открытия соединения с внешней базой данных

Синтаксис
SQL код (1)
SELECT dblink_connect([строка соединения]::text) [ AS | INTO ] result::text;
SELECT dblink_connect([имя соединения]::text, [строка соединения]::text) [ AS | INTO ] result::text;
Описание

dblink_connect устанавливает соединение с внешней базой данных PostgreSQL. Связь организуется через стандартную библиотеку libpq с соответсвующим синтаксисом. Если используется несколько подключений к внешним серверам, то каждому соединению можно назначить имя, так как одновременно поддерживается только одно неименованное соединение. Связь сохраняется в пределах сессии или до принудительного остоединения (dblink_disconnect).

(для версии 8.4) Конструкция соединения так же может быть именем существующего внешнего сервера заведенного в базе данных. Для внешних серверов рекомендуется использовать обертку postgresql_fdw_validator.

Аргументы

имя соединения - необязательный текстовый параметр который именует создаваемое соединение.

строка соединения - обязательный текстовый параметр, строка соединения в стиле libpq например: 'hostaddr=127.0.0.1 port=5432 dbname=mydb user=postgres password=mypasswd'. Так же может быть именем внешнего сервера.

Возвращаемые данные

Всегда возвращает 'OK' в тексте, если же во время соединения возникла ошибка, то возвращает ошибку и безусловно прерывает выполнение функции(!).

Примечание

Только пользователь с привилегией SUPER может открывать соединения, если у пользователя такой привилегии нет, то можно импользовать функцию dblink_connect_u.

Если мы открываем именованное соединение, то перед этой операцией желательно проверить нет ли соединений с таким же имененем с помощью dblink_get_connections, так как в противном случае мы получим ошибку. Для неименованного соединения этой проблемы нет, мы може открывает его несколько раз подряд.

Следует быть внимательным при установке подключений "на лету" внутри функций, так как ошибка подключения безусловно останавливает выполнение пользовательской функции. Но ошибка возвращается стандартная для PostgreSQL (код: 08001), поэтому можно создать процедуру подключения к удаленной базе и повесить на неё EXEPTION, например так:

SQL код (2)
CREATE OR REPLACE FUNCTION remote_db_connect(db_alias TEXT, db_server TEXT)
    RETURNS TEXT AS
$BODY$
DECLARE
  connectings       TEXT[];
  res               TEXT;
BEGIN
-- Проверяем не подключена ли уже база:
    SELECT dblink_get_connections() INTO connectings;
-- База уже подключена
    IF storage_name = ANY (connectings) THEN
        RETURN 'OK';
    ELSE
-- База не подключена, подключаем
        SELECT dblink_connect(db_alias, db_server) INTO res;
        RETURN res;
    END IF;
EXCEPTION
--  Если у нас ошибка подключения к внешней базе, то возвращаем 'ERR', еще выдадим системное сообщение
WHEN sqlclient_unable_to_establish_sqlconnection THEN
    RAISE NOTICE 'Error! Can not connect to server %, by aliases %', db_server, db_alias;
    RETURN 'ERR';
END;
$BODY$
  LANGUAGE 'plpgsql' STABLE;

Неправильно использовать имена соединения с вимволом "=", так как в некоторых функциях dblink может посчитать, что это не имя соединения, а другое выражение.

Пример
SQL код (3)
mybase=> SELECT dblink_connect('dbname=postgres');
dblink_connect
----------------
OK
(1 row)

mybase=> SELECT dblink_connect('myconn', 'dbname=postgres');
dblink_connect
----------------
OK
(1 row)

-- FOREIGN DATA WRAPPER functionality
-- Note: local connection must require password authentication for this to work properly
--       Otherwise, you will receive the following error from dblink_connect():
--       ----------------------------------------------------------------------
--       ERROR:  password is required
--       DETAIL:  Non-superuser cannot connect if the server does not request a password.
--       HINT:  Target server's authentication method must be changed.
mybase=> CREATE USER dblink_regression_test WITH PASSWORD 'secret';
mybase=> CREATE FOREIGN DATA WRAPPER postgresql VALIDATOR postgresql_fdw_validator;
mybase=> CREATE SERVER fdtest FOREIGN DATA WRAPPER postgresql OPTIONS (hostaddr '127.0.0.1', dbname 'contrib_regression');

mybase=> CREATE USER MAPPING FOR dblink_regression_test SERVER fdtest OPTIONS (user 'dblink_regression_test', password 'secret');
mybase=> GRANT USAGE ON FOREIGN SERVER fdtest TO dblink_regression_test;
mybase=> GRANT SELECT ON TABLE foo TO dblink_regression_test;

mybase=> \set ORIGINAL_USER :USER
mybase=> \c - dblink_regression_test
mybase=> SELECT dblink_connect('myconn', 'fdtest');
dblink_connect 
----------------
OK
(1 row)

mybase=> SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
a  | b |       c       
----+---+---------------
 0 | a | {a0,b0,c0}
 1 | b | {a1,b1,c1}
 2 | c | {a2,b2,c2}
 3 | d | {a3,b3,c3}
 4 | e | {a4,b4,c4}
 5 | f | {a5,b5,c5}
 6 | g | {a6,b6,c6}
 7 | h | {a7,b7,c7}
 8 | i | {a8,b8,c8}
 9 | j | {a9,b9,c9}
10 | k | {a10,b10,c10}
(11 rows)

mybase=> \c - :ORIGINAL_USER
mybase=> REVOKE USAGE ON FOREIGN SERVER fdtest FROM dblink_regression_test;
mybase=> REVOKE SELECT ON TABLE foo FROM  dblink_regression_test;
mybase=> DROP USER MAPPING FOR dblink_regression_test SERVER fdtest;
mybase=> DROP USER dblink_regression_test;
mybase=> DROP SERVER fdtest;
mybase=> DROP FOREIGN DATA WRAPPER postgresql;
Оригинал

http://www.postgresql.org/docs/8.4/static/contrib-dblink-connect.html

Сергей Томулевич aka Phoinix (23.09.2009 ред. 29.09.2009 г.)
Valid HTML 4.01 Transitional
Copyright © 2011 Сергей Томулевич