Oracle列是否有自动修改时间戳类型?

Ayr*_*rad 20 sql oracle

有没有办法在Oracle中创建一个时间戳列,自动存储记录更改时间的时间戳?

dka*_*man 19

很确定你必须在Oracle中使用触发器执行此操作:

create or replace TRIGGER parkedorder_tbiur
   BEFORE INSERT OR UPDATE
   ON parkedorder
   REFERENCING OLD AS old_row NEW AS new_row
   FOR EACH ROW
BEGIN
   IF INSERTING
   THEN
      IF :new_row.ID IS NULL
      THEN
         SELECT parkedorder_seq.NEXTVAL
           INTO :new_row.ID
           FROM DUAL;
      END IF;
   END IF;

   IF    :new_row.lastupdated <> SYSDATE
      OR :new_row.lastupdated IS NULL
   THEN
      SELECT sysdate
        INTO :new_row.lastupdated
        FROM DUAL;
   END IF;

   SELECT SYS_CONTEXT ( 'USERENV', 'OS_USER' )
     INTO :new_row.lastupdatedby
     FROM DUAL;
END;
Run Code Online (Sandbox Code Playgroud)

  • 聪明的触发器.对于后代的启迪,这似乎做了三件事.它将主键设置为顺序ID,它将最后更新的时间设置为当前时间,并将"最后更新时间"设置为我以前从未见过的一些神秘的东西,但我收集它以某种方式获取用户名.+1 (3认同)
  • 你不需要第二个if.您正在插入,所以只需设置lastupdated值.如果允许执行插入的用户覆盖lastupdated字段,则<> SYSDATE极易发生本地时间与服务器错误.更好地无条件地执行lastupdated值.此外,您可以将该sql语句与最后一个语句结合使用,以减少触发器内的语句数. (3认同)

Dav*_*ill 15

是的,通过触发器:

create or replace
TRIGGER schema.name_of_trigger
BEFORE INSERT OR UPDATE ON schema.name_of_table
FOR EACH ROW
BEGIN
    :new.modified_on := SYSTIMESTAMP;
END;
Run Code Online (Sandbox Code Playgroud)

假设您的表有一个名为modified_on的字段.

如上所述,只要您有多个表更新的不同位置,触发器就是理想的候选者.如果您只有一个可以更新表的函数/过程,只需在那里执行,然后跳过触发器.


小智 7

对于oracle,我通常使用触发器来更新时间戳字段

CREATE OR REPLACE TRIGGER update_timestamp 
  BEFORE INSERT OR UPDATE ON some_table
  FOR EACH ROW
BEGIN
  :NEW.TS := systimestamp;
END;
Run Code Online (Sandbox Code Playgroud)

Oracle似乎没有用于将时间戳字段更新为当前时间戳的内置属性(与MySQL之类的其他数据库不同).


Dav*_*dge 6

您可以通过查询来了解这一点ORA_ROWSCN:http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns007.htm#sthref825

如果使用ROWDEPENDENCIES选项创建表,则更准确.

它实际上记录了记录的提交时间......

drop table tester 
/

create table tester (col1 number, col2 timestamp)
rowdependencies
/

insert into tester values (1, systimestamp)
/

(approximate five second pause)

commit
/

select t.ora_rowscn,
       SCN_TO_TIMESTAMP(t.ora_rowscn),
       t.col1,
       t.col2
from   tester t
/

ORA_ROWSCN             SCN_TO_TIMESTAMP(T.ORA_ROWSCN) COL1                   COL2
---------------------- ------------------------------ ---------------------- -------------------------
9104916600628          2009-10-26 09.26.38.000000000  1                      2009-10-26 09.26.35.109848000 
Run Code Online (Sandbox Code Playgroud)


OMG*_*ies 0

我建模的表始终包括:

  • CREATED_USER, VARCHAR2
  • CREATED_DATE日期
  • UPDATED_USER, VARCHAR2
  • UPDATED_DATE日期

...列。当您可以在 INSERT/UPDATE 的同时设置值时,为什么要实现触发器呢?

INSERT INTO TABLE (...CREATED_DATE, UPDATED_DATE) VALUES (...,SYSDATE, SYSDATE);

UPDATE TABLE
   SET ...,
       UPDATED_DATE = SYSDATE
Run Code Online (Sandbox Code Playgroud)

  • 因为很容易忘记这样做,而且只要有触发器,你就不会忘记。这归结于环境。如果您从不更改访问数据的 SQL,那么触发器就是一种浪费,这是正确的。但在大多数情况下,拥有一个触发器比“总是”记住设置它要容易得多 (25认同)
  • @David:我只允许单个存储过程更新给定的表,然后根据需要引用存储过程。触发器更容易被忽略,因为在查看存储过程时它们的存在“不”可见。 (3认同)
  • 如果用户可以直接访问,则会遇到更大的问题。 (3认同)
  • @David:创建的时间和时间很容易记住:使用非空约束。 (3认同)
  • &lt;shudder&gt;一旦数据库处于野外,您的控制权就会减少&lt;/&gt; (2认同)