При обновлении поля срабатывает триггер Дата изменения для всех записей, а не только для записи, которая изменяется - PullRequest
0 голосов
/ 04 июля 2019

Я делаю прайс-лист, который автоматически обновляет цены на основе определенных установленных переменных.

При изменении стоимости элементов (я знаю, что имена моих столбцов отстой) или затраченного времени, поле с измененной датой должно изменяться только для измененной записи, вместо этого поле с измененной датой изменяется для каждой записи в таблице.Есть несколько триггеров, которые срабатывают, чтобы обновить цены в таблице.

Я не знаю, как разделить этот файл, чтобы было легче получить доступ к базе данных, но прикреплена ссылка на базу данных (база libreoffice 6.2.3.2 с использованием встроенного firebird 3.0) https://drive.google.com/open?id=1dFedDfd2JtmvMk8ChVofDpSDN8hq0p_S

// Дата изменения триггера

CREATE TRIGGER TRGDATEMODIFIED for "tblPart"
    before insert or update Position 100
AS 
BEGIN 
new."Date Modified" = current_timestamp;
END

// Установить триггер общей цены (последний срабатывает, чтобы установить цену, все остальные триггеры устанавливают значения для)

CREATE TRIGGER TRGSETTOTALPRICE for "tblPart"
    After insert or update position 99
AS
BEGIN
IF (old."Price" is distinct from new."Price" or old."Labor Price" is distinct from new."Labor Price" )
Then
Update  "tblPart"
Set "Total Price" = (CEIL(("Price"+"Labor Price")/10)*10)+9;
END

// триггер, чтобы установить ценуэтот триггер TRGSETTOTALPRICE использует

CREATE TRIGGER TRGSETPARTPRICE for "tblPart"
    After insert or update Position 98
AS
BEGIN
IF (old."Cost" is distinct from new."Cost")
Then 
Update  "tblPart"
Set "Price" = "tblPart"."Cost" / ( 1 -(Select "tblVariables"."Margin"from "tblVariables")) ;
END

// Триггер, который использует вторую таблицу для значений, которые не принимают «новый» psuedotable

CREATE TRIGGER TRGSETPARTPRICE2 for "tblVariables"
    After insert or update Position 98
AS
BEGIN
IF (old."Margin" is distinct from new."Margin")
Then 
Update  "tblPart"
Set "Price" = "tblPart"."Cost" / ( 1 -(Select "tblVariables"."Margin"from "tblVariables")) ;
END

// и моя попытка изменить для правильной работы

CREATE TRIGGER TRGSETPARTPRICE2 for "tblVariables"
    Before insert or update Position 98
AS
BEGIN
IF (old."Margin" is distinct from new."Margin")
Then 
 new."Price" = (select "tblPart"."Cost" from "tblPart") / ( 1 -(Select "tblVariables"."Margin"from "tblVariables")) ;
END

// код, который должен обновлять все значения при изменении поля

CREATE TRIGGER TRGSETLABORPRICE for "tblVariables"
    after insert or update position 98
AS
BEGIN
IF (old."Time Segment" is distinct from new."Time Segment" or old."Margin" is distinct from new."Margin" )
Then
    update "tblPart"
    set "Labor Price" = 
    Ceil((((select "Overhead with Margin" from "tblVariables") / (60/(select "Time Segment"from "tblVariables")))* Ceil(("Time to Complete"."tblPart")/( select "Time Segment"from "tblVariables"))));
END 

// edit: исправлен весь код, но последний фрагмент кода кажется выполненным неправильно, но работаеттем не менее

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Вы выполняете безусловное обновление всех строк в таблице tblpart в триггерах TRGSETTOTALPRICE и TRGSETPARTPRICE.Вы не должны изменять целевую таблицу в триггере, подобном этому, вместо этого вы должны использовать перед триггером и выполнять изменение переменной контекста new.Эта переменная контекста является модифицируемой в триггере перед именно для этой цели.

То есть вы должны сделать:

CREATE TRIGGER TRGSETTOTALPRICE for "tblPart"
    before insert or update position 99
AS
BEGIN
    IF (old."Price" is distinct from new."Price" or old."Labor Price" is distinct from new."Labor Price" )
    Then
      new."Total Price" = CEIL((new."Price" + new."Labor Price") / 10) * 10 + 9;
END

и

CREATE TRIGGER TRGSETPARTPRICE for "tblPart"
    before insert or update Position 98
AS
BEGIN
    IF (old."Cost" is distinct from new."Cost")
    Then 
      new."Price" = new."Cost" / ( 1 - (Select "tblVariables"."Margin" from "tblVariables"));
END
0 голосов
/ 04 июля 2019

Необходимо выполнить объединение в «обновленной» или «вставленной» таблице, чтобы изменить только записи, затронутые триггером.Смотрите аналогичный ответ здесь: https://dba.stackexchange.com/questions/118648/how-to-reference-only-affected-rows-in-after-update-trigger

...