将 Firebird SQL 触发器翻译成 PG trigger/function

Translating Firebird SQL trigger to PG trigger/function

我正在尝试将 Firebird SQL 触发器代码转换为 PG 中的 trigger/function。

在下面,我收到关于“;”的语法错误在 "END;",我想我正确地更改了其余部分,但无法找出语法错误。

CREATE OR REPLACE FUNCTION purchase_q_ai0()
  RETURNS void as $$

    declare
    CB_QUANTITY integer;
    CB_QUANTITYONHAND integer;
    CB_BOT_ID keys;
    CB_ID keys;
    BOT_QUANTITY integer;
    BOT_QUANTITYONHAND integer;
    BOT_ID keys;
    TEMP_QUANTITY integer;

BEGIN
    /* Update cellarbook and bottle after INSERT
    quantitypurchase, quantityonhand, purchasevalueonhand and
    currentvalueonhand will be updated */
    if (new.quantity is Null) then
        TEMP_QUANTITY := 0;
    else
        TEMP_QUANTITY := new.quantity;

    /* get corresponding cellarbook info */
    select cellarbook.quantitypurchased, cellarbook.quantityonhand, cellarbook.fk_bottle_id, cellarbook.id
            from cellarbook
            where new.fk_cellarbook_id = cellarbook.id
            into cb_quantity, cb_quantityonhand, cb_bot_id, cb_id;

    if (CB_QUANTITY is null) then
        CB_QUANTITY := 0;
    if (CB_QUANTITYONHAND is null) then
        CB_QUANTITYONHAND := 0;

    /* get corresponding bottle info */
    select bottle.quantitypurchased, bottle.quantityonhand, bottle.id from bottle
           where bottle.id = cb_bot_id
           into bot_quantity, bot_quantityonhand, bot_id;

    if (BOT_QUANTITY is null) then
        BOT_QUANTITY := 0;
    if (BOT_QUANTITYONHAND is null) then
        BOT_QUANTITYONHAND := 0;

    /* update with new info */
    update cellarbook set cellarbook.quantitypurchased = (cb_quantity + temp_quantity),
                          cellarbook.quantityonhand = (cb_quantityonhand + temp_quantity),
                          cellarbook.purchasevalueonhand = (cellarbook.lastpurchaseprice * cellarbook.quantityonhand),
                          cellarbook.currentvalueonhand = (cellarbook.currentvalue * cellarbook.quantityonhand)
            where cellarbook.id = cb_id;
    update bottle set bottle.quantitypurchased = (bot_quantity + temp_quantity),
                      bottle.quantityonhand = (bot_quantityonhand + temp_quantity),
                      bottle.purchasevalueonhand = (bottle.lastpurchaseprice * bottle.quantityonhand),
                      bottle.currentvalueonhand = (bottle.currentvalue * bottle.quantityonhand)
           where bottle.id = bot_id;
END;
$$
LANGUAGE plpgsql;

您需要在以下区域正确使用END IF


if (new.quantity is Null) then
    TEMP_QUANTITY := 0;
else
    TEMP_QUANTITY := new.quantity;
End if;

if (CB_QUANTITY is null) then
   CB_QUANTITY := 0;
if (CB_QUANTITYONHAND is null) then
   CB_QUANTITYONHAND := 0;
End if;
End if;

if (BOT_QUANTITY is null) then
    BOT_QUANTITY := 0;
if (BOT_QUANTITYONHAND is null) then
    BOT_QUANTITYONHAND := 0;
End if;
End if;

PLPGSQL-CONDITIONALS

plpgsql 语言中的触发器函数总是需要 return trigger 并且它还需要适当的 return 语句。否则,您需要 END IF 您的 IF 语句并重组您的 SELECT INTO 语句:

CREATE OR REPLACE FUNCTION purchase_q_ai0() RETURNS trigger AS $$
DECLARE
  CB_QUANTITY integer;
  CB_QUANTITYONHAND integer;
  CB_BOT_ID keys;
  CB_ID keys;
  BOT_QUANTITY integer;
  BOT_QUANTITYONHAND integer;
  BOT_ID keys;
  TEMP_QUANTITY integer;
BEGIN
  /* Update cellarbook and bottle after INSERT
     quantitypurchase, quantityonhand, purchasevalueonhand and
     currentvalueonhand will be updated */
  IF (NEW.quantity IS NULL) then
    TEMP_QUANTITY := 0;
  ELSE
    TEMP_QUANTITY := NEW.quantity;
  END IF;

  /* get corresponding cellarbook info */
  SELECT cb.quantitypurchased, cb.quantityonhand, cb.fk_bottle_id, cb.id
  INTO cb_quantity, cb_quantityonhand, cb_bot_id, cb_id
  FROM cellarbook cb
  WHERE NEW.fk_cellarbook_id = cb.id;

  IF (CB_QUANTITY IS NULL) THEN
    CB_QUANTITY := 0;
  END IF;
  IF (CB_QUANTITYONHAND IS NULL) THEN
    CB_QUANTITYONHAND := 0;
  END IF;

  /* get corresponding bottle info */
  SELECT b.quantitypurchased, b.quantityonhand, b.id
  INTO bot_quantity, bot_quantityonhand, bot_id
  FROM bottle b
  WHERE b.id = cb_bot_id;

  IF (BOT_QUANTITY IS NULL) THEN
    BOT_QUANTITY := 0;
  END IF;
  IF (BOT_QUANTITYONHAND IS NULL) THEN
    BOT_QUANTITYONHAND := 0;
  END IF;

  /* update with new info */
  UPDATE cellarbook SET
    quantitypurchased = cb_quantity + temp_quantity,
    quantityonhand = cb_quantityonhand + temp_quantity,
    purchasevalueonhand = lastpurchaseprice * quantityonhand,
    currentvalueonhand = currentvalue * quantityonhand
  WHERE id = cb_id;

  UPDATE bottle SET
    quantitypurchased = bot_quantity + temp_quantity,
    quantityonhand = bot_quantityonhand + temp_quantity,
    purchasevalueonhand = lastpurchaseprice * quantityonhand,
    currentvalueonhand = currentvalue * quantityonhand
  WHERE id = bot_id;

  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

内部声明变量的大小写问题就交给你了(PostgreSQL推荐使用小写)。

顺便说一句,PostgreSQL 默认情况下不知道 keys 数据类型。除非您定义该数据类型,否则代码将不起作用。这可能是 Firebird 特有的东西,用作 PRIMARY KEY?在这种情况下,它很可能是一个 32 位整数,您将在 PostgreSQL 中使用 integer 数据类型。