Неявное преобразование поля даты в триггере pl / sql? - PullRequest
1 голос
/ 20 июня 2011

Мне нужно разработать триггер в PL / SQL (Oracle) before INSERT.

В этой таблице есть столбец (cdat) типа DATE.

Допустим, я делаю INSERT INTO myTbl (123,'12/05/2011');

В моем триггере :NEW.CDAT конвертируется в окончательной системе дат или это все еще varchar?

Нужно ли делать TO_DATE(:NEW.CDAT), чтобы получить значение даты?

Ответы [ 2 ]

1 голос
/ 20 июня 2011

Вам необходимо выполнить преобразование, если ваш параметр сеанса ' NLS_DATE_FORMAT ' не равен ' мм / дд / гггг '.

Например:

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 
1 голос
/ 20 июня 2011

: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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...