postgresql - обновление - видимость функции - PullRequest
1 голос
/ 27 июля 2011

Скажем, у меня есть функция copy (в целых числах, out из целых чисел) , которая создает в таблице mytable дубликат строки, указанной в параметре.Идентификатор новой строки возвращается.

Я хотел бы применить ОБНОВЛЕНИЕ к новой / дублирующейся строке вместо старой строки:

update mytable set field = ... where identifier = (select copy(1));

Это не похоже наРабота.Дубликат создан, но он все еще имеет старые значения.Я ожидаю, что новая строка еще не видна при оценке предложения where.То есть обновление не происходит.

Следующее также не работает:

update mytable set field = ... from copy(1) as c where identifier = c.copy;

Когда я пишу его в две строки, оно отлично работает:

select copy(1);
update mytable set field = ... where identifier = <value returned by copy(1)>;

У меня есть два вопроса:

(1) Можно ли это сделать в однострочнике?

(2) Можно ли написать правило перезаписи или триггер, чтобы я мог дажезаписать

update mytable set field = ... where identifier = 1;

, пока дубликат создается в фоновом режиме, а обновления применяются к дубликату / новой строке?Я не вижу решения, которое не заканчивается бесконечным циклом.

пример кода

drop table if exists t cascade;

create table t
(
    identifier  serial  primary key,
    title       text
);

create or replace function copy(in integer, out integer) as
$$
        begin
                insert into t (title) values ((select title from t where identifier = $1)) returning identifier into $2;
        end
$$ language plpgsql;

insert into t (title) values ('title - old');
update t set title = 'title - new' where identifier = (select copy(1));
select * from t;

Обратите внимание, что в copy () строка обычно выбирается в отдельную переменную.Для простоты я взял заголовок непосредственно в этом примере кода.

1 Ответ

1 голос
/ 27 июля 2011

Я думаю, что это не работает по той же причине, по которой вы не можете использовать возврат с утверждениями, кроме как начиная с PG 9.1.Это должно хорошо работать в 9.1:

drop table if exists t cascade;

create table t (
    identifier  serial  primary key,
    title       text
);

insert into t (title) values ('title - old');

with copy as (
insert into t (title) select title from t where identifier = 1
returning identifier
)
update t set title = 'title - new' from copy where t.identifier = copy.identifier;

select * from t;

Отредактировано: возможное предложение 9.0 не сработало.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...