我正在尝试制作简单的触发器功能(Postgresql),但我得到的错误'函数在所有这些情况下都没有返回任何行(只是简单的例子):
新:
UPDATE somewhere SET something = something - 1;
RETURN NEW;
旧:
UPDATE somewhere SET something = something - 1;
RETURN OLD;
当我在“删除之前”调用此功能时应该返回什么? (“插入/更新后”效果很好)
Tyvm提示!
要求的完整代码: 功能:
CREATE OR REPLACE FUNCTION pictogram_frequency_on_delete()
RETURNS trigger AS
$BODY$
DECLARE
new_frequency RECORD;
target_unit RECORD;
current_row RECORD;
units_with_same_type RECORD;
what RECORD;
BEGIN
SET search_path TO 'myScheme';
CASE TG_OP
WHEN 'DELETED' THEN what := OLD;
ELSE what:= OLD;
END CASE;
SELECT unit_type_uid INTO STRICT target_unit
FROM unit
WHERE unit_uid = what.unit_uid;
SELECT count(*) AS exists INTO STRICT current_row
FROM unit_type_pictogram utp
WHERE utp.pictogram_uid = what.pictogram_uid
AND utp.unit_type_uid = target_unit.unit_type_uid;
IF (current_row.exists = 0) THEN
RETURN what; /* return new/old doesnt work too */
END IF;
UPDATE unit_type_pictogram utp
SET frequency = frequency - 1
WHERE utp.pictogram_uid = what.pictogram_uid
AND utp.unit_type_uid = target_unit.unit_type_uid;
RETURN what; /* return new/old doesnt work too */
END
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
触发:
CREATE TRIGGER on_delete_frequency
BEFORE DELETE
ON unit_pictogram
FOR EACH ROW
EXECUTE PROCEDURE pictogram_frequency_on_delete();
答案 0 :(得分:1)
你应该RETURN OLD;
。
您的功能必须定义为RETURNS trigger
。
答案 1 :(得分:0)
每个语句触发器调用的触发器函数应始终使用 返回NULL。每行触发器调用的触发器函数可以返回 调用执行程序的表行(类型为HeapTuple的值)if 他们选择。在操作具有之前触发的行级触发器 以下选择:
它可以返回NULL以跳过当前行的操作。这指示执行程序不执行该行级操作 调用触发器(插入,修改或删除) 特别的表格行。)
仅对于行级INSERT和UPDATE触发器,返回的行将成为将要插入的行或将替换正在行的行 更新。这允许触发器功能修改行 插入或更新。
不打算导致其中任何一个的行级BEFORE触发器 这些行为必须小心返回,因为它的结果是同一行 传入的(即INSERT和UPDATE的NEW行) 触发器,DELETE触发器的OLD行)。
尝试这样的事情:
public class CROpportunityMaintMyExtension : PXGraphExtension<OpportunityMaint>
{
public virtual void CROpportunityProducts_MyAvailability_FieldSelecting(PXCache sender, PXFieldSelectingEventArgs e)
{
var row = (CROpportunityProducts) e.Row;
if (row == null)
{
e.ReturnValue = string.Empty;
return;
}
INLocationStatus locationStatus = PXSelectGroupBy<INLocationStatus,
Where<INLocationStatus.inventoryID, Equal<Required<CROpportunityProducts.inventoryID>>,
And2<Where<INLocationStatus.subItemID, Equal<Required<CROpportunityProducts.subItemID>>,
Or<Not<FeatureInstalled<PX.Objects.CS.FeaturesSet.subItem>>>>,
And<Where<INLocationStatus.siteID, Equal<Required<CROpportunityProducts.siteID>>,
Or<Required<CROpportunityProducts.siteID>, IsNull>>>>>,
Aggregate<Sum<INLocationStatus.qtyOnHand, Sum<INLocationStatus.qtyAvail>>>
>.Select(sender.Graph, row.InventoryID, row.SubItemID, row.SiteID, row.SiteID);
// Need to convert to transaction UOM... (this is always base units)
decimal? qtyOnHand = locationStatus?.QtyOnHand;
decimal? qtyAvail = locationStatus?.QtyAvail;
e.ReturnValue = $"Qty On hand = {qtyOnHand.GetValueOrDefault()} ; Qty Avail = {qtyAvail.GetValueOrDefault()}";
}
}