36

任何人都可以帮助我了解何时使用:NEW:OLD在 PLSQL 块中,我发现很难理解它们的用法。

4

16 回答 16

45

您通常使用触发器 中的术语: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并将包含新值。

于 2012-10-30T08:49:26.760 回答
30

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

更新 - :旧= 更新语句之前表中存在的值 触发 :新= 给更新新值

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

于 2016-05-10T12:27:04.590 回答
11

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

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

对于以下操作,分别为旧值和新值:

  1. INSERT - :old.value= NULL, :new value= 后插入值
  2. DELETE - :old.value= 预删除值, :new value= null
  3. UPDATE - :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);
于 2016-06-01T13:33:59.973 回答
6

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

于 2015-10-22T09:56:20.307 回答
3

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

它在触发器中使用很多,例如 Creation_Date 和 Modified_By 字段

于 2017-04-11T20:14:21.877 回答
3

: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;

希望这能解释新旧概念。

于 2018-06-19T17:10:51.833 回答
2

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

于 2018-01-30T20:25:14.730 回答
2

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

于 2018-09-30T16:08:19.117 回答
2

以简单的方式,

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

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

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

希望这可以帮助你..

于 2019-03-13T15:03:06.703 回答
2

这很简单

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;
于 2020-06-17T06:11:59.533 回答
1

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

于 2020-02-18T07:00:25.483 回答
1
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;
/
于 2020-03-06T05:37:59.657 回答
1

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

于 2020-12-04T22:53:54.413 回答
1

主要是这里指的词

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

于 2021-03-11T13:01:06.310 回答
1

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

于 2021-08-08T13:20:18.087 回答
0

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

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

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

于 2022-01-06T11:04:41.170 回答