在pl / sql触发器中隐式转换日期字段?

时间:2011-06-20 16:14:44

标签: oracle plsql

我需要在PL / SQL(Oracle)before INSERT中开发一个触发器。

在此表中有一个DATE类型的列(cdat)。

假设我做INSERT INTO myTbl (123,'12/05/2011');

在我的触发器中,:NEW.CDAT在最终日期系统中转换,或者它仍然是varchar?

我是否需要TO_DATE(:NEW.CDAT)来获取日期值?

2 个答案:

答案 0 :(得分:1)

:NEW.CDAT将成为约会对象。触发器中的:new:old变量始终是目标字段的类型。


我无法在Oracle文档中找到任何证实我的陈述的内容,但我能够设计一些实验证据:

CREATE TABLE test2 (a DATE);

CREATE OR REPLACE TRIGGER bu_test2
   BEFORE INSERT OR UPDATE
   ON test2
   FOR EACH ROW
DECLARE
   PROCEDURE type_test(in_type DATE) IS
   BEGIN
      DBMS_OUTPUT.put_line('date');
   END;
   PROCEDURE type_test(in_type VARCHAR2) IS
   BEGIN
      DBMS_OUTPUT.put_line('varchar2');
   END;
BEGIN
   type_test(:new.a);
END;

INSERT INTO test2
  VALUES   ('24-Mar-2011');

由于type_test被重载,Oracle将根据传入的类型选择要使用的过程。此脚本的结果为:

Table created.
Trigger created.
date
1 row created.

答案 1 :(得分:1)

如果会话参数“ NLS_DATE_FORMAT ”不是“ mm / dd / yyyy ”,则需要进行转换。

例如:

create table    myTbl  (id number, cdat date);
select *
from   nls_session_parameters ns
where  ns.parameter = 'NLS_DATE_FORMAT';

PARAMETER                    VALUE
-------------------------------------------------------
NLS_DATE_FORMAT              DD-MON-RR

在这种情况下,如果没有to_Date,您将收到错误:

insert into myTbl
values
    (123, '12/05/2011');

ORA-01843: not a valid month

您可以在会话级别,系统级别等更改此参数

zep@dev> alter session set NLS_DATE_FORMAT = 'mm/dd/yyyy';

Session altered

select *
from   nls_session_parameters ns
where  ns.parameter = 'NLS_DATE_FORMAT';

PARAMETER                VALUE
-------------------------------------------------------------------------------------
NLS_DATE_FORMAT          mm/dd/yyyy

insert into myTbl
    (id, cdat)
values
        (123, '12/05/2011');

1 row inserted

zep@dev> select *
      2  from   myTbl;

        ID CDAT
---------- -----------
       123 05/12/2011

在行级触发器上测试

truncate table Mytbl;
alter session set NLS_DATE_FORMAT = 'DD-MON-RR';       
create or replace trigger befins_myTbl
    before insert on myTbl
    for each row
declare
begin
    -- demo
    :new.cdat := :new.cdat + numtoyminterval(1,'YEAR');-- (demo trigger add 1 year )
end;

insert into myTbl
(id, cdat)
values
(123, '12/05/2011');

输出:ORA-01843:无效月

alter session set NLS_DATE_FORMAT = 'mm/dd/yyyy';

insert into myTbl
    (id, cdat)
values
    (123, '12/05/2011');
commit;

select *
from   myTbl;

输出

ID         CDAT
---------- -----------
123        12/05/2012