Запрос проверки SQL триггера Firebird

Относительно простой вопрос. Я пытаюсь выполнить оператор и проверить значение перед настройкой значения INSERT в триггере firebird. Я видел много примеров, в которых новое значение оценивается, а затем выполняются последующие операторы, но ни один из них, как я хочу. Легче показать...

SET TERM ^ ;
CREATE TRIGGER STOP_PREMIX_INSERT_PRODUCEDD FOR PRODUCEDD ACTIVE
BEFORE INSERT OR UPDATE POSITION 0
AS 
BEGIN
    IF ('SELECT COUNT(*) FROM RECIPESTEPS rs INNER JOIN RECIPES r on r.RECIPEID=rs.RECIPEID INNER JOIN PRODUCEDH h on h.RECIPEID=r.RECIPEID WHERE h.BATCHID=' || new.BATCHID || ' AND ' || new.SEQUENCENO || '=rs.SEQUENCENO AND ' || new.COMMODITYID || '=rs.COMMODITYID AND rs.NONWEIGHED=17;' > 0) then
    new.BATCHID=-1;
END^
SET TERM ; ^

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

Обычно IF (new.ID = 0) выполняет оператор 'blah'; будет работать, но когда я пишу этот триггер, он синтаксически принимается, но при изменении значения я получаю следующее сообщение об ошибке:

арифметическое исключение, числовое переполнение или усечение строки усечение строки справа При триггере 'STOP_PREMIX_INSERT_PRODUCECEDD' строка: 6, столбец: 5

Я могу быть с запятой или это может быть просто невозможно, в любом случае, любая помощь приветствуется.


person MxMave    schedule 09.03.2016    source источник
comment
Не то чтобы я знал Firebird, но похоже, что вы проверяете, больше ли строка SQL нуля. Может быть, вам нужно выполнить строку и сравнить результат?   -  person Joachim Isaksson    schedule 09.03.2016


Ответы (2)


Причина, по которой это не работает, заключается в том, что вы создаете строку, а затем сравниваете ее с целым числом. Полученное преобразование завершается ошибкой. Тот факт, что строка содержит что-то похожее на SQL, на самом деле не выполняет его.

Вместо этого вам нужно выполнить запрос, например, используя EXISTS:

SET TERM ^ ;
CREATE TRIGGER STOP_PREMIX_INSERT_PRODUCEDD FOR PRODUCEDD ACTIVE
BEFORE INSERT OR UPDATE POSITION 0
AS 
BEGIN
    IF (EXISTS (SELECT * 
                FROM RECIPESTEPS rs 
                INNER JOIN RECIPES r on r.RECIPEID=rs.RECIPEID 
                INNER JOIN PRODUCEDH h on h.RECIPEID=r.RECIPEID 
                WHERE h.BATCHID = new.BATCHID 
                AND rs.SEQUENCENO = new.SEQUENCENO
                AND rs.COMMODITYID = new.COMMODITYID
                AND rs.NONWEIGHED = 17)) then
      new.BATCHID=-1;
END^
SET TERM ; ^

Это, вероятно, более эффективно, чем select count(*), как в другом ответе, потому что Firebird не нужно будет запрашивать все строки, просто проверьте, есть ли одна или несколько.

person Mark Rotteveel    schedule 10.03.2016
comment
Спасибо за ответ. Первоначально я пробовал этот маршрут, но, к сожалению, Firebird не поддерживает предложение EXISTS, поэтому я пошел по маршруту COUNT. - person MxMave; 15.03.2016
comment
@MxMave Я не уверен, что вы имеете в виду, Firebird поддерживает exists, а также PSQL, как показано выше. - person Mark Rotteveel; 15.03.2016
comment
Извините, вы правы. На одном этапе я получал неизвестный термин EXISTS, должно быть, проблема заключалась в том, как я его структурировал. Это выполняется правильно. - person MxMave; 15.03.2016

Это должно быть так:

SET TERM ^ ;
CREATE TRIGGER STOP_PREMIX_INSERT_PRODUCEDD FOR PRODUCEDD ACTIVE
BEFORE INSERT OR UPDATE POSITION 0
AS 
  declare variable CNT integer;
BEGIN
    SELECT COUNT(*) FROM RECIPESTEPS rs INNER JOIN RECIPES r on r.RECIPEID=rs.RECIPEID INNER JOIN PRODUCEDH h on h.RECIPEID=r.RECIPEID WHERE h.BATCHID = new.BATCHID AND new.SEQUENCENO = rs.SEQUENCENO AND  new.COMMODITYID = rs.COMMODITYID AND rs.NONWEIGHED=17 into :CNT;
    IF (CNT > 0) then
        new.BATCHID=-1;
END^
SET TERM ; ^

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

person Maxim Votyakov    schedule 10.03.2016
comment
Идеальный. Я пробовал подобное, но я пытался сделать CNT = (), а не в: CNT. Огромное спасибо! - person MxMave; 15.03.2016