Тестировал на PostgreSQL версии 9.1. На версии 8.4 запрос отказывается работать.
Перед нами стоит задача обновить значения в таблицах измерений. Для примера выберем dim_test.
Первое, что приходит на ум - это использование функции merge. Однако для PostgreSQL функция не реализована.
Решение задачи - использование конструкции CTE для обновления таблиц измерений (обновление через PDI рассмотрим отдельно).
Какие допущения будем предполагать:
Нас не интересует как таблица (dim_test_source) попадает в нашу БД (можно использовать PDI, для перекидывания).
Вобщем схема такая:

Зададим таблицу dim_test:
CREATE SEQUENCE dim_test_seq;
CREATE TABLE dim_test
(
id_dim_test bigint NOT NULL DEFAULT nextval('dim_test_seq'::regclass),
id bigint,
name text,
last_name text,
CONSTRAINT id_dim_test_pk PRIMARY KEY (id_dim_test)
);
ALTER SEQUENCE dim_test_seq OWNED BY dim_test.id_dim_test ;
CREATE INDEX idx_dim_test_tk
ON dim_test
USING btree
(id_dim_test);
id_dim_test - это суррогатный ключ таблицы dim_test или в как встречается в литературе технический ключ.
id - это уникальный ключ dim_test_source.
Создаем входную таблицу dim_test_source:
CREATE SEQUENCE dim_test_source_seq;
CREATE TABLE dim_test_source
(
id bigint NOT NULL DEFAULT nextval('dim_test_source_seq'),
name text,
last_name text,
CONSTRAINT id_dim_source_pk PRIMARY KEY (id)
)
;
ALTER SEQUENCE dim_test_source_seq OWNED BY dim_test_source.id ;
Заполняем ее данными:
INSERT INTO dim_test_source("name", last_name) VALUES ( 'first','test_1');
INSERT INTO dim_test_source("name", last_name) VALUES ( 'second','test_1');
INSERT INTO dim_test_source("name", last_name) VALUES ( 'third','test_1');
Итак запрос обновления будет следующим:
WITH update_dim as
(
UPDATE dim_test
set "name"=dim_test_source."name",
last_name=dim_test_source.last_name
from dim_test_source where dim_test.id=dim_test_source.id
RETURNING dim_test_source.id
)
insert into dim_test ( id, "name", last_name)
select dim_test_source.id,
dim_test_source."name",
dim_test_source.last_name
from dim_test_source left join update_dim USING(id)
where update_dim.id isnull;
update_dim - таблица состоящая из ключей, у которых обновили запись:
Далее, обновим пару записей в таблице dim_test_source:
UPDATE dim_test_source SET name='third_V2' WHERE id = 3; UPDATE dim_test_source SET last_name='test_2' WHERE id = 2;
И добавим данных:
INSERT INTO dim_test_source("name", last_name) VALUES ( 'fourth','test_1');
INSERT INTO dim_test_source("name", last_name) VALUES ( 'fifth','test_1');
Запускаем запрос на обновление еще раз и получаем следующий результат.

Обновление прошло успешно.