postgresql: вставка dblink в удаленную базу данных

Это моя ситуация,

У меня есть две базы данных (db1, db2), обе с таблицей «страны». Мне это нужно, когда я вставляю в db1 .countries, автоматически вставляет в db2 .countries. Я использую модуль dblink для подключения ко второй базе данных.

Схема SQL таблицы стран:

CREATE TABLE countries (
  id INTEGER PRIMARY KEY,
  name VARCHAR(100) NOT NULL,
  flag VARCHAR(5) 
);

Чтобы справиться с этой ситуацией, на db1 я создал следующую процедуру:

CREATE OR REPLACE FUNCTION prc_insert_to_countries()
      RETURNS trigger AS
    $$
    DECLARE 
        insert_statement TEXT;
        res TEXT;
    BEGIN                
        perform dblink_connect('db2', 'dbname=db2 host=localhost 
        user=xxx password=xxx');

        insert_statement = 'insert into countries(id, name, flag) 
                                    values ('||NEW.id||', 
                                    '''||NEW.name||''', 
                                    '''||NEW.flag||'''
                                    );';
        res := dblink_exec('db2', insert_statement, true);
        RAISE INFO '%', res;
        perform dblink_disconnect('db2');
        RETURN NEW;
    END;
    $$
    LANGUAGE 'plpgsql';

И следующий триггер:

CREATE TRIGGER tr_countries
      AFTER INSERT
      ON countries
      FOR EACH ROW
      EXECUTE PROCEDURE prc_insert_to_countries();

Если я выполню следующий оператор вставки на db1:

INSERT INTO countries (id, name, flag) VALUES (1, 'Italy', 'ITA');

Все работает отлично, и вставленная строка также вставляется в db2 .countries. Но если я выполню:

INSERT INTO countries (id, name, flag) VALUES (1, 'Italy', NULL);

Вставленная строка не вставляется в db2 .countries ...

Я попытался решить эту проблему с помощью этого сообщения: триггер postgresql с dblink не возвращает ничего, но это не работает ...

Как я могу это решить?

Спасибо.


person Wildchild    schedule 02.02.2017    source источник
comment
Вероятно, это потому, что объединение (||) с NULL приводит к NULL (ваш insert_statement будет NULL). Кроме того, объединение операторов SQL открывает возможность для внедрения SQL. Используйте функцию format() вместо объединение вручную.   -  person pozs    schedule 02.02.2017
comment
или quote_nullable   -  person Roman Tkachuk    schedule 02.02.2017
comment
Использование функции format () отлично работает. Спасибо!   -  person Wildchild    schedule 02.02.2017


Ответы (1)


Поле NULL вызывает проблему, попробуйте использовать COALESCE для обработки NULL следующим образом:

insert_statement = 'insert into countries(id, name, flag) 
                                    values ('||NEW.id||', 
                                    '''||NEW.name||''', 
                                    '''||COALESCE(NEW.flag,'')||'''
                                    );';

Просто имейте в виду, что поле флага в удаленной базе данных получит пустую строку вместо NULL.

person ferbusson    schedule 30.09.2020