使用PostgreSQL。 我有的是: 3桌
1. Customer2c
包含以下列: CustomerID
,PersonID,
Number_Of_Items`。
2. SalesOrderHeader2c
包含列: SalesOrderID
,CustomerID
。
SalesOrderDetail2c
包含以下列: SalesOrderDetailID
,SalesOrderID
,OrderQty
我想创建一个触发器功能,只要有人使用
就会触发 INSERT INTO 'SalesOrderDetail2c' table
这将获得插入的OrderQty
并使用它更新对应的Number_Of_Items
字段。
我的触发器工作正常,但问题每当我向SalesOrderDetail2c插入一个新值时,该函数会获得OrderQty
值,而会更新{的所有行{1}}使用它,而不是只更新通讯者。
任何帮助表示赞赏。到目前为止我所拥有的是(这可能是完全错误的,请不要判断!):
Number_Of_Items
答案 0 :(得分:0)
我不得不使用.new作为上面提到的@Nicarus!再顺一句,再次感谢。
这是新代码,现在只更改对应的值。
CREATE OR REPLACE FUNCTION FunctionTrigger2c() RETURNS TRIGGER AS
$BODY$
BEGIN
UPDATE Customer2c
SET Number_Of_Items =
(SELECT new.OrderQty
FROM SalesOrderDetail2c
order by salesorderdetailid desc limit 1
)
FROM SalesOrderheader2c
WHERE (SalesOrderheader2c.salesorderID = new.salesorderID) and (salesorderheader2c.customerid = customer2c.customerid)
;
RETURN NEW;
END;
$BODY$
language plpgsql;
CREATE TRIGGER Trigger2c
AFTER INSERT ON SalesOrderDetail2c
FOR EACH ROW
EXECUTE PROCEDURE FunctionTrigger2c();
答案 1 :(得分:0)
这是我的,非常通用的触发器,用于在依赖表中执行count / sum值。您应该处理所有订单更改,即EXEC spGetNewCases '2016-03-01', '2016-05-01'
以及INSERT
和DELETE
。您还应该阅读@Nicarus关于在触发器中使用UPDATE
(和NEW
)的评论。
我更改了它以符合您的架构,但没有测试它......
OLD
如果您更改CREATE OR REPLACE FUNCTION FunctionTrigger2c()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
CASE TG_OP
WHEN 'INSERT' THEN
UPDATE
Customer2c
SET
Number_Of_Items = Number_Of_Items + NEW.OrderQty
FROM
SalesOrderHeader2c
WHERE
Customer2c.CustomerID = SalesOrderHeader2c.CustomerID AND
SalesOrderHeader2c.SalesOrderID = NEW.SalesOrderID AND
SalesOrderDetailID = NEW.SalesOrderDetailID;
WHEN 'UPDATE' THEN
UPDATE
Customer2c
SET
Number_Of_Items = Number_Of_Items - OLD.OrderQty
FROM
SalesOrderHeader2c
WHERE
Customer2c.CustomerID = SalesOrderHeader2c.CustomerID AND
SalesOrderHeader2c.SalesOrderID = OLD.SalesOrderID AND
SalesOrderDetailID = OLD.SalesOrderDetailID;
UPDATE
Customer2c
SET
Number_Of_Items = Number_Of_Items + NEW.OrderQty
FROM
SalesOrderHeader2c
WHERE
Customer2c.CustomerID = SalesOrderHeader2c.CustomerID AND
SalesOrderHeader2c.SalesOrderID = NEW.SalesOrderID AND
SalesOrderDetailID = NEW.SalesOrderDetailID;
WHEN 'DELETE' THEN
UPDATE
Customer2c
SET
Number_Of_Items = Number_Of_Items - OLD.OrderQty
FROM
SalesOrderHeader2c
WHERE
Customer2c.CustomerID = SalesOrderHeader2c.CustomerID AND
SalesOrderHeader2c.SalesOrderID = OLD.SalesOrderID AND
SalesOrderDetailID = OLD.SalesOrderDetailID;
END CASE;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
:), UPDATE
也能正常运作
注意,此触发器返回SalesOrderID
并且应设置为NULL
:
AFTER INSERT OR UPDATE OR DELETE
答案 2 :(得分:0)
我指出了您原来的触发器为何无效的原因。它更新每一行的原因是由于您的UPDATE语句。插入某些内容后,它触发了更新。 当更新运行时,它得到了这些东西:
问题出在最后一部分,基本上,在UPDATE语句中调用FROM就像调用SELECT语句一样,它试图处理具有给定WHERE值的FROM子句表中的每一行。
有关UPDATE语句from_list参数的PostgreSQL文档指出“ A 表表达式列表,允许其他表中的列 出现在WHERE条件和更新表达式中。这是 与可以在FROM子句中指定的表的列表相似 SELECT语句。” (https://www.postgresql.org/docs/9.1/sql-update.html)
基本上,您的更新语句遍历了 SalesOrderHeader2c 中的每一行,该行方便地与 Customer2c 的每一行匹配(具有 SalesOrderHeader2c.CustomerID = Customer2c.CustomerID ),使用UPDATE SET语句中第一个找到的 Number_Of_Items 值更新 Customer2c 中每一行的值。这就是为什么 Customer2c 中的每一行都具有相同值的原因。
新触发器起作用的原因是因为update语句是使用正确选择的行完成的。