Sql (postgres) - Как создать триггер, который умножает две строки из таблицы и добавляет им строку в другой таблице?

У меня есть две таблицы OrderItem и Orders. Я хотел обновить строку totalamount в таблице Orders для каждой вставки в OrderItem путем умножения количества и unitprice. Однако я не смог создать правильный триггер. Как создать триггер. Заранее спасибо!

вот моя таблица заказов:

      CREATE TABLE public.orders
(
  orderid integer NOT NULL DEFAULT nextval('orders_orderid_seq'::regclass),
  ordernumber integer NOT NULL,
  customerid integer NOT NULL,
  totalamount numeric(12,4) NOT NULL,
  orderdate timestamp without time zone DEFAULT now(),
  CONSTRAINT orders_pk PRIMARY KEY (orderid),
  CONSTRAINT orders_fk FOREIGN KEY (customerid)
      REFERENCES public.customer (customerid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
)

а вот моя таблица Orderitem:

 CREATE TABLE public.orderitem
(
  orderitemid integer NOT NULL DEFAULT nextval('orderitem_orderitemid_seq'::regclass),
  orderid integer NOT NULL,
  productid integer NOT NULL,
  unitprice numeric(12,4) NOT NULL DEFAULT 0,
  quantity integer NOT NULL,
  CONSTRAINT orderitem_pk PRIMARY KEY (orderitemid),
  CONSTRAINT orderitem_fk_order FOREIGN KEY (orderid)
      REFERENCES public.orders (orderid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE,
  CONSTRAINT orderitem_fk_product FOREIGN KEY (productid)
      REFERENCES public.product (productid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.orderitem
  OWNER TO postgres;

-- Trigger: unitprice on public.orderitem

-- DROP TRIGGER unitprice ON public.orderitem;

CREATE TRIGGER unitprice
  AFTER INSERT
  ON public.orderitem
  FOR EACH ROW
  EXECUTE PROCEDURE public.transferunitprice();

и функция триггера, которую я пробовал:

CREATE OR REPLACE FUNCTION public.increment_totalamount()
  RETURNS trigger AS
$BODY$
BEGIN
    SELECT Orderitem.unitprice * Orderitem.quantity + Orders.totalamount 
            INTO NEW.totalamount
    FROM Orderitem, Orders
    WHERE Orders.orderid = NEW.orderid;

    RETURN NEW;
END
$BODY$
  LANGUAGE plpgsql

Забыл добавить сам триггер:

CREATE TRIGGER increment_totalamount
  BEFORE INSERT
  ON public.orderitem
  FOR EACH ROW
  EXECUTE PROCEDURE public.increment_totalamount();

Пожалуйста, публикуйте DDL как текст, а не как изображения.

sticky bit 09.09.2018 00:37

хорошо, готово!

Mustafayl 09.09.2018 00:57
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Что-то в этом роде должно работать

CREATE OR REPLACE FUNCTION update_order_price() RETURNS TRIGGER
AS $update_order_price$
    DECLARE
        delta numeric(14, 2)
    BEGIN
        -- Work out the increment/decrement amount(s).
        IF (TG_OP = 'INSERT') THEN
            delta = NEW.quantity * NEW.unitprice;
        ELSIF (TG_OP = 'UPDATE') THEN
            delta = NEW.quantity * NEW.unitprice - OLD.quantity * OLD.unitprice;
        ELSIF (TG_OP = 'DELETE') THEN
            delta = - OLD.quantity * OLD.unitprice;
        END IF;

        -- Update the order row
        UPDATE orders 
        SET totalamount = totalamount + delta
        WHERE id = OLD.orderid;

        RETURN NEW;
    END;
$update_order_price$ LANGUAGE plpgsql;

Спасибо. Он работает с небольшими изменениями. Я еще не пробовал выполнять операции удаления.

Mustafayl 09.09.2018 01:29

Другие вопросы по теме