【问题标题】:PLSQL :NEW and :OLDPLSQL :NEW 和 :OLD
【发布时间】:2012-10-19 13:46:52
【问题描述】:

谁能帮助我了解何时在 PLSQL 块中使用 :NEW:OLD,我发现很难理解它们的用法。

【问题讨论】:

    标签: oracle plsql triggers


    【解决方案1】:

    您通常使用trigger 中的术语,使用:old 来引用旧值,:new 来引用新值。

    这是上面链接的 Oracle 文档中的一个示例

    CREATE OR REPLACE TRIGGER Print_salary_changes
      BEFORE DELETE OR INSERT OR UPDATE ON Emp_tab
      FOR EACH ROW
    WHEN (new.Empno > 0)
    DECLARE
        sal_diff number;
    BEGIN
        sal_diff  := :new.sal  - :old.sal;
        dbms_output.put('Old salary: ' || :old.sal);
        dbms_output.put('  New salary: ' || :new.sal);
        dbms_output.put_line('  Difference ' || sal_diff);
    END;
    

    在此示例中,触发器触发 BEFORE DELETE OR INSERT OR UPDATE :old.sal 将包含触发器触发之前的薪水,:new.sal 将包含新值。

    【讨论】:

    • 它们只是用于在触发触发之后和之前显示值还是它们的任何其他用途?
    • @Pravin 常见用例是验证和审计。使用上面的例子,假设需求是跟踪员工的工资历史,在这种情况下,我们可以将旧的工资、修改日期和用户名插入到历史表中。在我正在使用 ATM 的应用程序中,当编辑坐标时,触发器用于更新记录高度
    • 它们也不只是供参考:在插入或更新触发器之前,可以将值分配给 :new 值。一个常见的用途是在插入前触发器中为主键提供一个序列中的值。
    【解决方案2】:

    :new 表示您尝试插入的新值 :old 表示数据库中的现有值

    【讨论】:

      【解决方案3】:

      :New 和 :Old 值可以在 DML 语句中区分。
      Insert -- :Old = NULL :New=插入新值

      Update -- :Old = 更新语句触发之前表中存在的值 :New = 为更新赋予新值

      删除 -- :Old = 删除前的值 :New = NULL

      【讨论】:

        【解决方案4】:

        :old 和 :new 是使用行级触发器时访问行级数据的伪记录。

        • :old - 指旧值
        • :new - 指新值

        对于下面的操作,分别是旧值和新值:

        1. 插入- :old.value= NULL, :new value= 后插入值
        2. DELETE- :old.value= 预删除值,:new value= null
        3. 更新- :old.value= 更新前值, :new value= 更新后 价值

        例如:

        CREATE OR REPLACE TRIGGER get_dept
          BEFORE DELETE OR INSERT OR UPDATE ON employees
          FOR EACH ROW
        BEGIN
            DBMS_OUTPUT.PUT('Old Dept= ' || :OLD.dept|| ', ');
          DBMS_OUTPUT.PUT('New Dept= ' || :NEW.dept );
        END;
        

        触发语句:

        UPDATE employees
        SET dept ='Accounts'
        WHERE empno IN (101 ,105);
        

        【讨论】:

        • 如果语句使用 AFTER 而不是 BEFORE,那么 OLD 在 insert 中为 null 而 NEW 在 delete 中为 null 的行为会改变吗?
        • @Sawd 不,它没有。但是,在 BEFORE(插入或更新)触发器中,您可以修改值,并且修改最终会出现在保存的记录中。
        【解决方案5】:

        :old 是你的旧值 :new 是你的新值,

        它在触发器中被大量使用,例如 Creation_Date 和 Modified_By 字段

        【讨论】:

          【解决方案6】:

          :new 是新值 - 触发触发器后,这是列的值 :old 是旧值 - 触发触发器后,此值将替换为 :新价值

          【讨论】:

            【解决方案7】:

            :old 和 :new 是使用行级触发器时访问行级数据的伪记录。

            •:old - 指旧值 •:new - 指新值

            例如:

            CREATE OR REPLACE TRIGGER mytrig BEFORE
              INSERT OR
              UPDATE
                ON mytab FOR EACH ROW
            BEGIN
              IF INSERTING THEN
                SELECT trunc(sysdate), trunc(sysdate) INTO :new.created, :NEW.last_updated FROM DUAL;
              END IF; --INSERTING
            
              IF UPDATING THEN
            
                  SELECT trunc(sysdate) INTO :NEW.last_updated FROM DUAL;
            
              END IF; --UPDATING
            
            END;
            

            希望这能解释新旧概念。

            【讨论】:

              【解决方案8】:

              New 和 Old 与触发器内的更新操作更相关,获取字段的旧值使用 old,最近的值使用 new

              【讨论】:

                【解决方案9】:

                简单来说,

                当您将数据操作到表中时,触发器将触发。所以在触发调用时,你有两个价值。一个是指旧数据值,一个是您最近更新/删除/插入的新数据值。 以防

                插入-旧值将为空,新值包含一些值 更新 - 新旧都有一些价值 删除 - 旧有价值,但新不会包含价值。

                因此,通过使用 :OLD 和 :NEW,您可以插入/更新要维护历史记录的其他表,或者基于 :OLD 或 :NEW 值,您可以插入/更新其他一些依赖表。

                希望这对您有所帮助..

                【讨论】:

                  【解决方案10】:

                  :OLD 和 :NEW 是 Record 类型的变量,并且在列中与触发触发器的表行相同。它们仅适用于行级触发器。由于触发器会在预定义的事件上自动触发,因此 :OLD 和 :NEW 也会自动获取它们的值。顾名思义, :OLD 将有完整的行值存在于表中(即在更新和删除的情况下具有现有值)并且 :NEW 将具有该行的新值(即在更新和删除的情况下具有行值)插入)。

                  【讨论】:

                    【解决方案11】:
                    A simple example that shows the use of old and new using triggers
                    
                    CREATE TABLE emp_log(
                    emp_id NUMBER;
                    updated_by DATE,
                    new_salary VARCHAR2(15),
                    Action VARCHAR2(20));
                    
                    CREATE OR REPLACE TRIGGER log_sal 
                    AFTER UPDATE OF sal on emp
                    FOR EACH ROW
                    BEGIN
                    INSERT INTO emp_log( emp_id, updated_by, new_salary, Action)
                    VALUES(:NEW.empno, USER, :NEW.sal, 'New salary');
                    END;
                    /
                    

                    【讨论】:

                      【解决方案12】:

                      很简单

                      If Insert :old = NULL and :New = New Inserted Value
                      If Update  :Old = Value already in the table  :New = Updated Value in the Table
                      If Delete :Old = Value before deletion :New = NULL
                      

                      换句话说

                      1. 对于 INSERT 触发器,OLD 不包含任何值,而 NEW 包含 新的价值观。

                      2. 对于 UPDATE 触发器,OLD 包含旧值,NEW 包含 新值。

                      3. 对于 DELETE 触发器,OLD 包含旧值,NEW 包含 没有值。

                      例子:

                      CREATE OR REPLACE TRIGGER update_name_view_trigger
                      INSTEAD OF UPDATE ON emp_locations
                      BEGIN
                        UPDATE employees SET
                          first_name = substr( :NEW.name, instr( :new.name, ',' )+2),
                          last_name = substr( :NEW.name, 1, instr( :new.name, ',')-1)
                        WHERE employee_id = :OLD.employee_id;
                      END;
                      

                      【讨论】:

                        【解决方案13】:

                        您可以在 100% 的更新之后/之前使用 :OLD :NEW 是(插入或更新)添加的新值的记录 :OLD 用于旧值。 没有它们,触发器就没用了

                        【讨论】:

                          【解决方案14】:

                          这里主要是指的话

                          :old 指触发触发前的旧值。 :new 包含触发后触发的值。

                          【讨论】:

                            【解决方案15】:

                            在尝试进行任何数据库修改(更新)时,您可能会遇到这种情况。当您插入(添加/新)数据时,:New 会出现。由于您没有任何现有数据,因此没有任何内容显示为:Old。当您通过代码更新现有详细信息时,您将看到现有数据为:Old,更新后的详细信息为:New

                            【讨论】:

                              【解决方案16】:

                              在触发器主体中,:OLD 和 :NEW 关键字使您能够访问受触发器影响的行中的列

                              :OLD 用于在更新或删除之前获取列的旧值。因此 OLD 仅与删除或更新语句触发器一起使用

                              :NEW 用于获取更新或刚刚插入数据库的值。因此 NEW 与唯一的更新和插入语句触发器一起使用

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 2018-12-19
                                • 2018-04-06
                                • 2014-02-15
                                • 2016-03-21
                                • 1970-01-01
                                • 1970-01-01
                                • 2018-11-30
                                • 2020-11-10
                                相关资源
                                最近更新 更多