2016-03-09 2 views
2

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

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, col: 5

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

+3

Не знаю, что я знаю Firebird, но похоже, что вы проверяете, больше ли строка SQL больше нуля. Может быть, вам нужно выполнить строку и сравнить результат? –

ответ

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 не нужно будет запрашивать все строки, просто проверить что есть один или несколько.

+0

Спасибо за ответ. Я пробовал этот маршрут изначально, но, к сожалению, Firebird не поддерживает предложение EXISTS, похоже, поэтому я пошел по маршруту COUNT. – MxMave

+1

@MxMave Я не уверен, что вы имеете в виду, Firebird поддерживает 'exist', а также в PSQL, как показано выше. –

+0

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

2

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

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 ;^

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

+0

Отлично. Я пробовал подобное, но я пытался сделать CNT =(), а не в: CNT. Огромное спасибо! – MxMave

Смежные вопросы