什么应该返回触发BEFORE DELETE

时间:2017-07-11 11:54:36

标签: postgresql database-trigger

我正在尝试制作简单的触发器功能(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();

2 个答案:

答案 0 :(得分:1)

你应该RETURN OLD;

您的功能必须定义为RETURNS trigger

答案 1 :(得分:0)

来自documentation

  

每个语句触发器调用的触发器函数应始终使用   返回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()}";
    }
}