Установка значения для результата подзапроса в функции в postgresql - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь написать функцию для триггера, которая проверяет, больше ли дата в новой записи в отношении, чем запись в другом отношении. Если это так, я хочу обновить значение даты в моем новом отношении до значения даты в моем другом отношении:

create or replace function curDate()
returns trigger as $$
Begin
    if (new.date >= (select date from other where new.name = other.name )) then
        set new.date = (select date from playlist where new.name = other.name );
    end if;
end; $$ language plpgsql;

Я получаю синтаксическую ошибку: set new.date = (select date from playlist where new.name = other.name )

Тем не менее, это прекрасно работает:

create or replace function curDate()
    returns trigger as $$
    declare dateVar date;
Begin
    dateVar := (select date from other where new.name = other.name);
    if (new.datum >= dateVar) then
        new.datum = dateVar;
    end if;
end; $$ language plpgsql;

Почему это?

Ответы [ 2 ]

0 голосов
/ 06 января 2019

Предполагая все задействованные столбцы NOT NULL и other.name UNIQUE, чтобы избежать осложнений.

Использовать один SELECT назначение запроса NEW.datum:

CREATE OR REPLACE FUNCTION trg_cur_date()
  RETURNS TRIGGER AS
$func$
BEGIN
   SELECT o.datum
   FROM   other o
   WHERE  o.name  = NEW.name
   AND    o.datum < NEW.datum

   UNION ALL SELECT NEW.datum
   LIMIT  1

   INTO   NEW.datum;

   RETURN NEW;  -- required for BEFORE INSERT trigger
END
$func$  LANGUAGE plpgsql;

Для триггера типа:

CREATE TRIGGER playlist_ins_bef
BEFORE INSERT ON playlist
FOR EACH ROW EXECUTE PROCEDURE trg_cur_date();

дБ <> скрипка здесь

SELECT INTO ( не следует путать с SQL SELECT INTO, использование которого не рекомендуется ) может сделать назначение как = или :=. № SET здесь.

Если ни одна строка не подходит, простой SELECT INTO присваивает NULL. Руководство:

... target будет установлен на первую строку, возвращаемую запросом, или на NULL, если запрос не возвращает строк.

Добавление UNION ALL SELECT NEW.datum LIMIT 1 по умолчанию вместо исходного значения. См:

Таким образом, мы только когда-либо выполняем один запрос с одним назначением.

0 голосов
/ 06 января 2019

Чтобы сохранить результат запроса в переменной, используйте , выберите

create or replace function curDate()
returns trigger as $$
Begin
  if (new.date >= (select date from other where new.name = other.name )) then
    select date 
      into new.date 
    from other 
    where new.name = other.name;
  end if;
end; $$ language plpgsql;

Это может быть дополнительно оптимизировано путем запуска SELECT только один раз.

create or replace function curDate()
returns trigger as $$
declare
   l_date date;
Begin
  select date 
    into l_date
  from other 
  where new.name = other.name;

  if (new.date >= l_date) then
    new.date := l_date;
  end if;
end; $$ language plpgsql;
...