Триггер предотвращает вставку данных в таблицу - PullRequest
0 голосов
/ 29 ноября 2018

У меня следующая проблема: я пытаюсь вставить данные в таблицу, однако мой триггер не позволяет мне выполнить вставку.Мой триггер состоит в том, чтобы вставить codigolle в таблицу журнала, когда введен «год» <'2000', но я сталкиваюсь со следующей ошибкой: </p>

"ОШИБКА: у запроса нет места назначения для данных результата СОВЕТ: Если вы хотите отменить результаты SELECT, используйте вместо этого PERFORM. КОНТЕКСТ: функция PL / pgSQL funcaotriggerxx () строка 5 в операторе SQL "

TRIGGER

CREATE FUNCTION funcaoTriggerXX() RETURNS trigger AS $valor$
DECLARE
    cod INT;
BEGIN
    SELECT codigolivro 
    FROM edicao
    WHERE ano < '2000';

    cod = codigolivro;

    INSERT INTO log (codigolivro) VALUES (cod);

    RETURN cod;
END;
$valor$ LANGUAGE plpgsql;

CREATE TRIGGER codigoLivros AFTER INSERT ON edicao
EXECUTE PROCEDURE funcaoTriggerXX();

PROCEDURE

CREATE OR REPLACE FUNCTION seculoxx()
RETURNS integer AS $total2$
declare
    total2 integer;
BEGIN
   SELECT count(*) into total2 
   FROM edicao
   WHERE ano < 2000;
   RETURN total2;
END;
$total2$ LANGUAGE plpgsql;

SELECT

SELECT seculoxx();

INSERT

INSERT INTO edicao (codigolivro, numero, ano) VALUES ('1325','4','1990');

Структура таблицы также проста: edicao

  • код (числовой)
  • Версия (символ)
  • Год (целое число)

log

  • codigolivro

Можеткто-нибудь поможет мне?

Ответы [ 2 ]

0 голосов
/ 29 ноября 2018

Посмотрите, как отличаются ваши запросы на выборку в funcaoTriggerXX и seculoxx.Если вы хотите сохранить значение из выбранного запроса, вам нужно SELECT column_name INTO variable_name.Если вы не хотите сохранять результат, вам нужно использовать PERFORM.например.PERFORM SELECT ....

Существует также несоответствие между вашим языком и тем, что будет делать код.То есть вы говорите:

Мой триггер состоит в том, чтобы вставить кодигол в таблицу журнала, когда вводится «год» <«2000» </p>

Полагаю, вы имеете в видуcodigolivro для строки, которая была только что вставлена.Однако так оно и есть.Этот триггер по существу вставит случайную строку с year < 2000, если любая строка в таблице edicao удовлетворяет этому условию.Вместо этого вы можете использовать специальную переменную NEW, чтобы получить только что вставленную строку, и вы можете использовать предложение WHEN в CREATE TRIGGER, чтобы контролировать, когда срабатывает ваш триггер.

Так как вас волнует толькоЧто касается только что вставленной строки (не всех строк во всей таблице), то вы можете использовать специальную переменную NEW.

CREATE FUNCTION funcaoTriggerXX() RETURNS trigger AS $valor$
BEGIN
    INSERT INTO log (codigolivro) VALUES (NEW.codigolivro);
    RETURN NEW;
END;
$valor$ LANGUAGE plpgsql;

CREATE TRIGGER codigoLivros AFTER INSERT ON edicao
    FOR EACH ROW
    WHEN (NEW.ano < 2000)
    EXECUTE PROCEDURE funcaoTriggerXX();
0 голосов
/ 29 ноября 2018

Во-первых, ваша триггерная функция сообщает, что возвращает trigger (NULL / OLD / NEW), когда фактически возвращает INTEGER.Тогда, как говорится в ошибке, вы не можете сделать SELECT в функции plpgsql без адресата.Другими словами, вам нужно присвоить результат вашего оператора SELECT переменной.

SELECT codigolivro 
    INTO cod
FROM edicao
WHERE ano < '2000';

Ваша функция seculoxx() в порядке, но не нуждается в промежуточной переменной:

RETURN count(*)
FROM edicao
WHERE ano < 2000;
...