Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Web программирование > SQL, базы данных
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.09.2016, 12:17   #1
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию триггер на обновление

Здравствуйте!
Помогите, пожалуйста, с триггером.

Есть две таблицы: product - в ней содержатся данные о товаре и category - данные о категориях товаров

В таблице product есть два поля: cost_price - себестоимость и retail_price - цена продажи, которая рассчитывается как произведение: cost_price * category_mark_up (наценка из таблицы category).

Код триггера на вставку отрабатывает нормально, retail_price считается верно. Вот сам код:
Код:
CREATE TRIGGER i_trigger_retail_price
    ON product
    AFTER INSERT
AS
BEGIN
    DECLARE @rt INT
    DECLARE @cp INT
    DECLARE @cmu FLOAT
 
SELECT @cp = cost_price
FROM product
WHERE id_product = (SELECT id_product FROM inserted)
 
SELECT @cmu = category_mark_up
FROM category 
WHERE id_category = (SELECT id_category FROM inserted)
 
SET @rt = @cp*@cmu
 
UPDATE product SET retail_price = @rt WHERE id_product = (SELECT id_product FROM inserted)
 
END

Проблема с триггером на обновление. Я думал, что по сути он работает также, то есть код практически тот же:

Код:
CREATE TRIGGER u_trigger_retail_price
    ON product
    AFTER UPDATE
AS
BEGIN
    DECLARE @rt INT
    DECLARE @cp INT
    DECLARE @cmu FLOAT
 
SELECT @cp = cost_price
FROM product
WHERE id_product = (SELECT id_product FROM inserted)
 
SELECT @cmu = category_mark_up
FROM category 
WHERE id_category = (SELECT id_category WHERE category.id_category = (product.id_category FROM inserted))
 
SET @rt = @cp*@cmu
 
UPDATE product SET retail_price = @rt WHERE id_product = (SELECT id_product FROM inserted)
 
END
На деле выходит, что retail_price реагирует на изменение cost_price. Но совсем не реагирует на изменение category_mark_up.

Подскажите, пожалуйста, что надо подправить в коде.

Пробовал с реализацией через старые и новые значения (inserted / deleted), но совсем не пошло
Изображения
Тип файла: jpg Безымянный.jpg (28.6 Кб, 161 просмотров)
don_zaresh вне форума Ответить с цитированием
Старый 17.09.2016, 12:33   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

а почему триггер на таблице product должен реагировать на изменение в таблице category?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.09.2016, 12:51   #3
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию

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

А вот с триггером на обновление не понимаю, как сделать. Хотя логика вроде та же. Если меняется наценка category_mark_up для данного id_product, то цена retail_price должна пересчитываться.

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

Что делать? Соединять таблицы через JOIN?

А ведь одна из переменных может и не меняться. Тогда как? Проверить сначала, изменилось ли поле?
don_zaresh вне форума Ответить с цитированием
Старый 17.09.2016, 12:54   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

наценка на категории обновляется в другой таблице.
вы обратите внимание на какую таблицу триггер то висит.
Цитата:
Что делать? Соединять таблицы через JOIN?
JOIN это для селектов, на триггеры это не влияет.
вешать триггер на обновление в таблицу category, и там(если изменилось) пересчитывать все продукты этой категории(один апдейт всего)
Цитата:
А ведь одна из переменных может и не меняться. Тогда как? Проверить сначала, изменилось ли поле?
обязательно.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.09.2016, 13:00   #5
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию

Вашу мысль то я понял. Но допустим я создам триггер на обновление наценки category_mark_up и навешу его на таблицу category.

Но потом же как-то надо увязать новые значения? Формула расчета у меня в первом триггере. То есть все равно придется объявлять в первом триггере переменную, принимающую значение наценки.

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


Я правильно понимаю, что:
1) пишем второй триггер на обновление наценки и вешаем его на таблицу category
2) код первого триггера по сути не меняется, то есть AS INSERT, UPDATE
don_zaresh вне форума Ответить с цитированием
Старый 17.09.2016, 13:03   #6
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию

Не увидел ваше отредактированное сообщение.

А как может выглядеть код - условие на проверку изменения поля category_mark_up?
don_zaresh вне форума Ответить с цитированием
Старый 17.09.2016, 22:27   #7
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию

Пепел Феникса, дайте, пожалуйста, ссылку на пример, как это делается. Или поделитесь кодом. Честное слово, уже мыслей нет, как это надо реализовать )

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

Последний раз редактировалось don_zaresh; 17.09.2016 в 22:56.
don_zaresh вне форума Ответить с цитированием
Старый 18.09.2016, 07:58   #8
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Примерно так, писано на коленке
Код:
//Тут еще будет в пустую вызов триггера на обновление
CREATE TRIGGER product_insert ON product AFTER INSERT AS
BEGIN
  UPDATE product
    SET retail_price = I.cost_price*C.category_mark_up
    FROM product P,inserted I,category C
    WHERE P.id_product=I.id_product AND
          C.id_category=I.id_category
END
GO

//Тут рекурсии не будет, если только не установлен RECURSIVE_TRIGGERS
CREATE TRIGGER product_update ON product AFTER UPDATE AS
BEGIN
  UPDATE product
    SET retail_price = I.cost_price*C.category_mark_up
    FROM product P,inserted I,category C,deleted D
    WHERE P.id_product=I.id_product AND
          C.id_category=I.id_category AND
          I.id_product=D.id_product AND
          I.cost_price<>D.cost_price
END
GO

//Тут еще будет в пустую вызов триггера на обновление product
CREATE TRIGGER category_update ON category AFTER UPDATE AS
BEGIN
  UPDATE product
    SET retail_price = P.cost_price*I.category_mark_up
    FROM product P,inserted I,deleted D
    WHERE P.id_category=I.id_category AND
          I.id_category=D.id_category AND
          I.category_mark_up<>D.category_mark_up
END
GO
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 18.09.2016, 14:22   #9
don_zaresh
 
Регистрация: 10.02.2016
Сообщений: 9
По умолчанию

Аватар, спасибо! Сейчас буду разбираться. А что значит, "не будет рекурсии"?
don_zaresh вне форума Ответить с цитированием
Старый 18.09.2016, 14:26   #10
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Цитата:
что значит, "не будет рекурсии
внутри триггера обновление таблицы, для которой есть триггер на обновление. В том случае он не будет вызываться
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Триггер Svyatoslav359 SQL, базы данных 0 25.05.2016 22:07
Триггер Babur4iK SQL, базы данных 3 08.11.2012 16:28
Обновление DataSet. Триггер. _SERGEYX_ БД в Delphi 2 08.09.2010 15:31
Триггер Neymexa SQL, базы данных 1 01.04.2010 18:50
Триггер? yulia БД в Delphi 9 12.05.2007 15:03