【问题标题】:Oracle SQL Trigger insert/update---Oracle SQL 触发器插入/更新---
【发布时间】:2013-07-01 03:11:09
【问题描述】:

请帮我解决这个问题,我想编写一个触发器,只要源表中发生插入/更新,我就可以将值插入到新表中。

下面是我要从中获取数据到另一个表的表结构。

列表

Name Null Type


LISTINGID NOT NULL VARCHAR2(28)
LISTINGMANAGERID NOT NULL VARCHAR2(28)
MANAGEAVAILABILITYFLAG VARCHAR2(1)
AVAILABILITYTEXT VARCHAR2(2000)

AREAINQUIRYFLAG VARCHAR2(1)
COUNTRYTEXT VARCHAR2(50)
STATEPROVINCETEXT VARCHAR2(50)
CITYTEXT VARCHAR2(50)
CHECKINTIME VARCHAR2(10)
CHECKOUTTIME VARCHAR2(10)
TIMEZONEID VARCHAR2(20)

PERSONALLINKURL VARCHAR2(150)

GOLDSUBSCRIPTIONSINCE DATE
AUDITPASSFLAG NOT NULL VARCHAR2(1)
MGRONLINEFLAG NOT NULL VARCHAR2(1)
ADMINAPPROVALFLAG NOT NULL VARCHAR2(1)
DELETEDFLAG VARCHAR2(1)
LASTUPDATED NOT NULL DATE
UPDATEDBY NOT NULL VARCHAR2(28)
OCA NOT NULL NUMBER(38)
SUSPENDEDFLAG NOT NULL VARCHAR2(1)
POSSIBLEFEATUREDCITYFLAG NOT NULL VARCHAR2(1)
TOTALPHOTOS NUMBER(38)
SUSPENDEDDATE DATE
OFFLINEDATE DATE
CURRENCY VARCHAR2(3)
POINTCHARGE VARCHAR2(2)
AVERAGEOFREVIEWS FLOAT(126)
@ 987654351@
RENTALMODEL VARCHAR2(10)
NOTHANKS VARCHAR2(1)
DIGITALSIGN VARCHAR2(50)

需要下表中的结果以及列表表中的任何更新或新插入。

i)listingid 应该包含列表中的listingid。

ii)OFFLINE COLUMN 应包含具有以下条件的数据。

AuditPassFlag = 'Y' AND AdminApprovalFlag='Y' AND MgrOnlineFlag='Y' AND DeletedFlag 为 NULL AND SuspendedFlag !='Y'

iii)TIMESTAMP COLUMN 列表中的最后更新日期。

LISTING_LASTUPDATE TABLE

名称空类型


LISTINGID NOT NULL VARCHAR2(20)

IS_OFFLINE VARCHAR2(1)

TIMESTAMP TIMESTAMP(0)

在我写的触发器下面:

它在 where 条件下无法正常工作,这意味着列表在线:除此之外它工作正常。

CREATE OR REPLACE TRIGGER listingLast_updated
   AFTER INSERT OR UPDATE
   ON listing
   FOR EACH ROW

DECLARE
   L_Listingid             VARCHAR2 (20);

   L_ISOFFLINE             VARCHAR2 (1);

   LASTUPDATED_TIMESTAMP   DATE;
BEGIN
   SELECT SYSDATE INTO LASTUPDATED_TIMESTAMP FROM DUAL;

   IF (    :NEW.AuditPassFlag = 'Y'
       AND :NEW.AdminApprovalFlag = 'Y'
       AND :NEW.MgrOnlineFlag = 'Y'
       AND :NEW.DeletedFlag IS NULL
       AND :NEW.SuspendedFlag != 'Y') THEN
      L_ISOFFLINE := 'Y';
   ELSE
      L_ISOFFLINE := 'N';

      INSERT
        INTO LISTING_LastUPDATED (LISTINGID, IS_OFFLINE, LASTUPDATED_TIMESTAMP)
      VALUES (:NEW.LISTINGID, L_ISOFFLINE, LASTUPDATED_TIMESTAMP);
   END IF;
END;

【问题讨论】:

  • 这不是代码编写服务。创建触发器的某些特定方面是否需要帮助?我敢肯定,Oracle 花了很多钱来编写他们的文档,而且它非常好。也许尝试阅读它 - docs.oracle.com/cd/B28359_01/appdev.111/b28370/triggers.htm
  • @OldProgrammer:我已经分享了写的tirgger,请看一下。
  • 什么意思,不工作 - 运行时错误,还是编译错误?您的触发代码中没有“WHERE”。请更具体。

标签: triggers oracle11g procedure ora-04091


【解决方案1】:

你写过:

需要下表中的结果以及列表表中的任何更新或新插入。

这不是您的触发器的作用。再看看你的 IF 语句。它简化为:

if ... then
   ...
else
   insert ...
end if;

您的 INSERT 在 ELSE 子句中。因此,当初始 IF 语句为真时,您将执行 INSERT。不是“有任何更新或新插入”

您还可以更改许多其他内容:

  1. 变量L_Listingid从未使用过,删除它。

  2. 无需使用 SELECT INTO ... 来分配变量。这可以在声明块中按如下方式完成:

    lastupdated_timestamp date := sysdate;
    

    但是,我认为没有特别需要存在此变量,因此您可以删除它并在您的唯一 INSERT 中简单地使用 SYSDATE。

  3. 根本不需要执行 ELSE。将L_ISOFFLINE 的默认值设置为 N,然后在 IF 条件不为真时使用它。

  4. 两个外观变化,无需将 AND 括在括号中;我已将触发器名称添加到 END,以便更清晰。

你也写过:

TIMESTAMP COLUMN 列表中的最后更新日期。

实际上,您的 LISTING 表中有 LASTUPDATED 日期,这意味着您没有遵循自己的准则。您应该改用该列。

将所有这些放在一起,您的触发器可能如下所示:

create or replace trigger listinglast_updated
   after insert or update
   on listing
   for each row
declare

   l_isoffline varchar2(1) := 'N';

begin

   if :new.auditpassflag = 'Y'
       and :new.adminapprovalflag = 'Y'
       and :new.mgronlineflag = 'Y'
       and :new.deletedflag is null
       and :new.suspendedflag != 'Y' then

      l_isoffline := 'Y';

   end if;

   insert into listing_lastupdated (listingid, is_offline, lastupdated_timestamp)
   values (:new.listingid, l_isoffline, :new.lastupdated);

end listinglast_updated;

【讨论】:

  • 感谢 Ben 的 cmets...我已经重写并从触发器中删除了不必要的东西。我没有使用列表表中的 LastUpdated,因为我希望有时间和日期,我不能在基表中进行更改。
  • 所以您只是将:new.lastupdated 替换为sysdate 然后@Aryan?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2021-02-26
  • 2017-06-26
相关资源
最近更新 更多