Is there an automatic modification time stamp type for Oracle columns?

前端 未结 6 2124
臣服心动
臣服心动 2020-12-15 05:46

Is there a way to create a timestamp column in Oracle that automatically stores a timestamp of when the record has changed ?

相关标签:
6条回答
  • 2020-12-15 05:47

    Yes, via a trigger:

    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;
    

    This assumes your table has a field called modified_on.

    As has been noted above, a trigger is an ideal candidate anytime you have multiple different places where the table gets updated. If you only have one function/procedure that can update the table, just do it there, and skip the trigger.

    0 讨论(0)
  • 2020-12-15 05:57

    Tables I've modelled always include:

    • CREATED_USER, VARCHAR2
    • CREATED_DATE, DATE
    • UPDATED_USER, VARCHAR2
    • UPDATED_DATE, DATE

    ...columns. Why implement a trigger when you can set the value at the same time as the INSERT/UPDATE?

    INSERT INTO TABLE (...CREATED_DATE, UPDATED_DATE) VALUES (...,SYSDATE, SYSDATE);
    
    UPDATE TABLE
       SET ...,
           UPDATED_DATE = SYSDATE
    
    0 讨论(0)
  • 2020-12-15 05:59

    For oracle I usually use a trigger to update the timestamp field

    CREATE OR REPLACE TRIGGER update_timestamp 
      BEFORE INSERT OR UPDATE ON some_table
      FOR EACH ROW
    BEGIN
      :NEW.TS := systimestamp;
    END;
    

    Oracle does not seem to have a built-in attribute for updating the timestamp field to the current timestamp (unlike other DBs like MySQL).

    0 讨论(0)
  • 2020-12-15 06:04

    Pretty sure you have to do this with a trigger in 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;
    
    0 讨论(0)
  • 2020-12-15 06:11

    Another way to deal with this is by turning on fine-grained audit. The individual rows won't have a timestamp, but you'll have a record of all changes. Overkill in most situations, though -- I usually just use triggers.

    If you are OK with nearest .01 seconds, you can use date format and assign sysdate. If you need more detail, use the timestamp.

    0 讨论(0)
  • 2020-12-15 06:12

    You can get very close to this by querying ORA_ROWSCN: http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/pseudocolumns007.htm#sthref825

    This is more accurate if you created the table with the ROWDEPENDENCIES option.

    It actually logs the commit time for the record ...

    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 
    
    0 讨论(0)
提交回复
热议问题