2015-08-18 1 views
0

Я хочу спросить о регистрации ошибок DML в Oracle У меня есть оригинальный стол с этой структуройOracle DML типа Протоколирование ошибок поле

table_test(
ID Int PK, 
test_time date 
) 

Я также создать таблицу протоколирования ошибок для этого ERR $ _table_test

Насколько я знаю, в поле «ID' и» test_time' в ERR$_table_test является VARCHAR(4000)

Позвольте мне взять пример

1. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) 

==> успешно, 1 строка вставляется

2. Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) 

==> 0 строка вставляется в table_test, 1 строка в ERR $ _table_test с этой ошибкой: ORA-00001: ограничение уникальности нарушается

3. select * from ERR$_table_test 

1 запись найдено: но поле test_time является '18/08/2015' , не имея времени < == Я хочу полный штамп времени для этого поля

После этого, я пытаюсь изменить таблицу ERR $ _table_test

alter table ERR$_table_test modify test_time date 

я переделать точно выше пример

На этот раз я получил полную отметку времени test_time в ERR $ _table_test

Но, тогда я попробуйте

Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss')) 

==> ошибка SQL происходит, когда вставки неправильного типа в ERR $ _table_test

Это вещь, которую я обеспокоен

  1. Могу ли я получить полную временную отметку в $ ERR _table_test без изменения его типа столбца?

  2. Если мне нужно изменить тип столбца на DATE, могу ли я получить журнал ошибок для второго случая, когда неправильный формат времени?

Спасибо за любую поддержку,

+1

Вы пытались запустить 'alter session set nls_date_format = 'dd/mm/yyyy hh24: mi: ss');' в сеансе перед тем, как делать вставку? – Boneist

ответ

2

Если можно оценить дату, то она преобразует его обратно в строку поместить в varchar2(4000) колонки, используя параметры сеанса. Поскольку это поле даты вы можете контролировать, что, установив NLS_DATE_FORMAT перед выполнением вставки:

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS'; 

Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test; 

Insert into table_test values (1,to_date('18/08/2015 15:00:00' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test; 

Insert into table_test values (2,to_date('abc xyz' , 'dd/mm/yyyy hh24:mi:ss')) log errors into err$_table_test; 

column id format a10 
column test_time format a20 
select ora_err_number$, id, test_time from ERR$_table_test; 

         ORA_ERR_NUMBER$ ID   TEST_TIME   
--------------------------------------- ---------- -------------------- 
             1 1   2015-08-18 15:00:00 
            1858 2   abc xyz   

который не является идеальным, особенно если вы, возможно, вставка из нескольких клиентов, настройки которых вы не можете контролировать.

Но the documentation ноты, если вы используете даты типа данные в вашей лесозаготовительной таблице ошибок, а не рекомендуется (и по умолчанию, если он создано с помощью DBMS_ERRLOG) varchar2(4000), неспособность конвертировать - как с вашей abc xyz значения - заставят все заявление о сбое:

Because type conversion errors are one type of error that might occur, the data types of the optional columns in the error logging table must be types that can capture any value without data loss or conversion errors. (If the optional log columns were of the same types as the DML table columns, capturing the problematic data into the log could suffer the same data conversion problem that caused the error.) The database makes a best effort to log a meaningful value for data that causes conversion errors. If a value cannot be derived, NULL is logged for the column. An error on insertion into the error logging table causes the statement to terminate.

Так что, чтобы ответить на второй вопрос, нет; если вы измените тип данных журнала ошибок на DATE, то вы не получите ошибок, зарегистрированных в неверных форматах даты и времени, утверждение просто прекратится.

+0

Спасибо, я пробовал, и он работает, но есть ли какой-либо вариант, кроме изменения nls_date_format для текущего сеанса, потому что мой оператор SQL будет запускаться автоматически в скрипте с другими, поэтому я боюсь, что это изменение может повлиять на остальные – mrzenky

+0

@mrzenky - вы не должны иметь ничего в своем скрипте, который полагается на NLS_DATE_FORMAT. Вот почему это не идеально, поскольку он добавляет, что уверенность; но поскольку Oracle делает неявное преобразование, я не вижу другого пути. Вы могли, я полагаю, захватить и сбросить исходную настройку; но это действительно не имеет смысла, если только у вас есть только несколько операторов с включенным протоколированием ошибок. –