2017-02-07 13 views
0

У меня есть скрипт SQL для триггеров. Он автоматически генерировался большим программным обеспечением для моделирования базы данных под названием «Win'Design».Ошибка написания сценария триггера на PostgreSQL

Итак, после создания базы данных со всеми таблицами (0 данных) я хотел скопировать/вставить скрипт в редактор запросов pgAdmin.

Вот выдержка:

-- Trigger de modification ---------------------------------------------- 
CREATE TRIGGER TU_SOURCE_OPEN_DATA 
AFTER UPDATE ON SOURCE_OPEN_DATA FOR EACH ROW 
EXECUTE PROCEDURE 
    -- Interdire la modification de la clé étrangère référençant la table 
    -- SOURCE_PARAMETRE. 

    if 
      :OLD.ID_SOURCE_PARAMETRE <> :NEW.ID_SOURCE_PARAMETRE 
    then 
       raise_application_error(
       -20008, 
       'Modification de la clé étrangère référençant "SOURCE_PARAMETRE" interdite.'); 
    end if; 

/

DROP TRIGGER TI_SOURCE_OPEN_DATA; 

-- Trigger d'insertion ---------------------------------------------- 
CREATE TRIGGER TI_SOURCE_OPEN_DATA 
AFTER INSERT ON SOURCE_OPEN_DATA FOR EACH ROW 
EXECUTE PROCEDURE 
    -- Sauf valeur nulle autorisée, interdire la création d'une occurrence de SOURCE_OPEN_DATA 
    -- s'il n'existe pas d'occurrence correspondante dans la table SOURCE_PARAMETRE. 

    select count(*) into numrows 
    from SOURCE_PARAMETRE 
    where 
      :NEW.ID_SOURCE_PARAMETRE = SOURCE_PARAMETRE.ID_SOURCE_PARAMETRE; 
    if 
      (
      numrows = 0 
     ) 
    then 
      raise_application_error(
       -20002, 
       'Impossible d''ajouter "SOURCE_OPEN_DATA" car "SOURCE_PARAMETRE" n''existe pas.'); 
    end if; 

/



-- ------------------------------------------------------------------------------- 
-- Table : SECTEUR 
-- ------------------------------------------------------------------------------- 

DROP TRIGGER TD_SECTEUR; 

-- Trigger de suppression ---------------------------------------------- 
CREATE TRIGGER TD_SECTEUR 
AFTER DELETE ON SECTEUR FOR EACH ROW 
EXECUTE PROCEDURE 
    -- Supprimer les occurrences correspondantes de la table INTERESSE. 

    delete from INTERESSE 
    where 
      INTERESSE.ID_SECTEUR = :OLD.ID_SECTEUR; 

/

и вот сообщение об ошибке:

ERROR: syntax error at or near ":" 
LINE 9:   :OLD.ID_SOURCE_PARAMETRE <> :NEW.ID_SOURCE_PARAMET... 
       ^
********** Error ********** 

ERROR: syntax error at or near ":" 
SQL state: 42601 
Character: 304 

я попытался удалить до "Trigger вставки d'" и по-прежнему есть ошибка

ERROR: syntax error at or near "select" 
LINE 9:  select count(*) into numrows 
      ^
********** Error ********** 

ERROR: syntax error at or near "select" 
SQL state: 42601 
Character: 369 

1-й раз с использованием триггеров ... пожалуйста, помогите

EDIT: Как @Laurenz Albe и @pozs правильно указали, это действительно синтаксис оракула. Это нечетно, как я указал во время извлечения PostgreSQL. Так что я попытался с другой Postgre9.1 и создан этот скрипт:

-

------------------------------------------------------------------------------- 
-- Table : SOURCE_OPEN_DATA 
-- ------------------------------------------------------------------------------- 

DROP TRIGGER TU_SOURCE_OPEN_DATA; 

-- TRIGGER DE MODIFICATION -------------------------------- 

CREATE TRIGGER TU_SOURCE_OPEN_DATA 
AFTER UPDATE ON SOURCE_OPEN_DATA 
REFERENCING OLDROW, NEWROW 
FOR EACH ROW 

IMPORT 
import java.sql.* ; 
BEGIN 
    -- Interdire la modification de la clé étrangère référençant la table 
    -- SOURCE_PARAMETRE. 

    if 
      OLDROW.getValue(10, CHAR);.ID_SOURCE_PARAMETRE <> NEWROW.getValue(10, CHAR);.ID_SOURCE_PARAMETRE 
    then 
       raise_application_error(
       -20008, 
       'Modification de la clé étrangère référençant "SOURCE_PARAMETRE" interdite.'); 
    end if; 

END; 

DROP TRIGGER TI_SOURCE_OPEN_DATA; 

-- TRIGGER D'INSERTION -------------------------------------- 

CREATE TRIGGER TI_SOURCE_OPEN_DATA 
AFTER INSERT ON SOURCE_OPEN_DATA 
REFERENCING OLDROW, NEWROW 
FOR EACH ROW 

IMPORT 
import java.sql.* ; 
BEGIN 

END; 

Опять же, это всего лишь отрывок. Теперь я получаю

ERROR: syntax error at or near ";" 
LINE 11: DROP TRIGGER TU_SOURCE_OPEN_DATA; 
             ^
********** Error ********** 

ERROR: syntax error at or near ";" 
+1

Здесь нельзя использовать синтаксис Oracle. Создайте [триггерную функцию] (https://www.postgresql.org/docs/current/static/plpgsql-trigger.html) ('RETURNS trigger') и используйте эту функцию в [' CREATE TRIGGER'] (https://www.postgresql.org/docs/current/static/sql-createtrigger.html). –

+1

Это просто неверный синтаксис для PostgreSQL. Из вызовов функции 'raise_application_error' кажется, что он может быть сгенерирован для Oracle. Если это возможно, создайте эти сценарии для PostgreSQL. – pozs

+1

'... interdire la création d'une появление de SOURCE_OPEN_DATA - s'il n'existe pas d'presence Соответствие dans la table SOURCE_PARAMETRE' Именно для этого предназначены ограничения внешнего ключа. – joop

ответ

1

TL; DR; Это не правильный синтаксис триггера PostgreSQL и имеет некоторые ошибки, которые, я думаю, не будут работать ни в одной другой базе данных.

В PostgreSQL вы не можете выполнить инструкцию SQL как процедуру для триггера. Вам нужно создать фактическую процедуру/функцию и поставить ее для триггера.

В дополнение к этому условию IF отсутствуют некоторые части (тип ROW, на которые он ссылается) и имеет точки с запятой без причины. Trigger не имеет доступа к NEWROW, вместо этого он называется NEW.

Нет ключевого слова REFERENCING для триггеров PostgreSQL, вместо этого есть ключевое слово FROM, но не должно использоваться в большинстве случаев.

SELECT INTO требует объявления переменной, поэтому вам нужен язык plpgsql вместо простого SQL.

--example trigger procedure 
CREATE OR REPLACE FUNCTION prevent_update() RETURNS TRIGGER AS $func$ 
BEGIN 
    RAISE EXCEPTION 'You cannot modify whatever column'; 
    RETURN OLD; --not really needed 
END; 
$func$ LANGUAGE plpgsql; 

--example trigger 
CREATE TRIGGER TU_SOURCE_OPEN_DATA 
AFTER UPDATE ON SOURCE_OPEN_DATA 
FOR EACH ROW 
WHEN (OLD.ID_SOURCE_PARAMETRE IS DISTINCT FROM NEW.ID_SOURCE_PARAMETRE) 
EXECUTE PROCEDURE prevent_update(); 

В дополнение к этому, вы можете использовать на разрешение столбца в PostgreSQL, если вы не хотите, чтобы определенные пользователи имели возможность изменять данные в определенных областях. Но если я правильно помню, это вызовет ошибку, даже если вы сделаете что-то вроде:

UPDATE table SET column1 = column1; 

Таким образом, вы должны были бы полностью исключить эту колонку.

0

Вы можете попробовать удалить: из: OLD и: NEW. Вы можете видеть в документации (https://www.postgresql.org/docs/9.2/static/plpgsql-trigger.html), нет : перед старым и новым.

+0

. Изменив пункт назначения из PostgreSQL на Postgre9.1, он также изменил скрипт. См. Править. Он также изменил: OLD и: NEW –

+1

Вы пытались: DROP TRIGGER TU_SOURCE_OPEN_DATA на SOURCE_OPEN_DATA; –

+0

Это сделало трюк! это первый шаг –