Триггер: показ ошибки при попытке вставить слишком длинный текст

140907
Дата: 14.10.2015 19:20:31
Здравствуйте.
Есть таблица с колонкой "comments".

create table schema01.table01 ( id number(21), comments varchar2(1000 byte) );


Надо сделать так, чтобы при попытке вставить комментарий больше 1000 выдавалась простая и понятная ошибка.
Делаю триггер.

create or replace trigger schema01.table01_tr
before insert or update
on schema01.table01 for each row
declare
v_comments number;
begin
-- этот вариант не работает
  select length(:new.comments) into v_comments from dual;
  if v_comments > 1000 then raise_application_error(-20001,'Длина комментария - не более 1000.');
  end if;
-- этот вариант тоже не работает
  if length(:new.comments) > 1000 then raise_application_error(-20001,'Длина комментария - не более 1000.');
  end if;
-- и этот вариант не работает
  if :new.comments > 1000 then raise_application_error(-20001,'Длина комментария - не более 1000.');
  end if;
end table01_tr;
/


Т.е. вставить текст больше 1000 не удается, но при этом выдается оракловая ошибка, а не моя. А мне нужна моя :)
Что я делаю не так?
-2-
Дата: 14.10.2015 19:32:09
140907
простая и понятная ошибка
критерии простоты и понятности? может достаточно использовать русский язык для сессии. Пользователь работает в sqlplus или какое приложение? почему бы приложению не работать "по понятиям".
140907
Дата: 14.10.2015 19:46:10
Надо выводить произвольный текст на русском языке. Кроме того, пользователь взаимодействует с БД через браузер, поэтому к этому произвольному тексту надо применять html-форматирование. В общем, нужно вызывать именно такие (нестандартные) ошибки.
140907
Дата: 14.10.2015 19:50:23
Подобные триггеры нормально работают при сравнении числовых данных. А с текстом что-то не получается, и я не понимаю почему.

Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
PL/SQL Release 11.2.0.2.0 - Production
ArtNick
Дата: 14.10.2015 20:48:57
140907,
lengthb
-2-
Дата: 14.10.2015 21:17:24
140907
Кроме того, пользователь взаимодействует с БД через браузер, поэтому к этому произвольному тексту надо применять html-форматирование. В общем, нужно вызывать именно такие (нестандартные) ошибки.
Не понял, чем применение форматирования к произвольному тексту отличается для "нестандартных ошибок". Но сама идея - садизм: хоть чем-нибудь нагрузить систему и поиздеваться над пользователем, позволять ввести больший объем, чтобы после кропотливого набивания войны-и-мира, отправки лишних данных в бд и получении ответа обратно ткнуть носом в сообщение об ошибке.
И кстати, в случае войны-и-мира, надеешься, что любой объем дойдет до проверки в триггере?
SY
Дата: 14.10.2015 21:45:56
140907
Подобные триггеры нормально работают при сравнении числовых данных. А с текстом что-то не получается, и я не понимаю почему.


Потому-что проверка данных на вшивость происходит до INSET/UPDATE независимо от типа данных. И с числами тоже:

SQL> create table tbl(n number(1));

Table created.

SQL> create or replace
  2    trigger tbl_bir
  3    before insert
  4    on tbl
  5    for each row
  6    begin
  7        if :new.n >= 10 then raise_application_error(-20500,'N must by less than 10'); end if;
  8  end;
  9  /

Trigger created.

SQL> insert into tbl values(99);
insert into tbl values(99)
                       *
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column


SQL> 


А ты скорее всего использовал "безразмерный" NUMBER:

SQL> create table tbl(n number);

Table created.

SQL> create or replace
  2    trigger tbl_bir
  3    before insert
  4    on tbl
  5    for each row
  6    begin
  7        if :new.n >= 10 then raise_application_error(-20500,'N must by less than 10'); end if;
  8  end;
  9  /

Trigger created.

SQL> insert into tbl values(99);
insert into tbl values(99)
            *
ERROR at line 1:
ORA-20500: N must by less than 10
ORA-06512: at "SCOTT.TBL_BIR", line 2
ORA-04088: error during execution of trigger 'SCOTT.TBL_BIR'


SQL> 


Кстати, с числами еще сложнее чем со строками, ибо они еще и округляются при превышении размерности дробной части:

SQL> create table tbl(n number(*,1));

Table created.

SQL> create or replace
  2    trigger tbl_bir
  3    before insert
  4    on tbl
  5    for each row
  6    begin
  7        if :new.n >= 10 then raise_application_error(-20500,'N must by less than 10'); end if;
  8  end;
  9  /

Trigger created.

SQL> insert into tbl values(9.25);

1 row created.

SQL> select * from tbl;

         N
----------
       9.3

SQL> insert into tbl values(9.95);
insert into tbl values(9.95)
            *
ERROR at line 1:
ORA-20500: N must by less than 10
ORA-06512: at "SCOTT.TBL_BIR", line 2
ORA-04088: error during execution of trigger 'SCOTT.TBL_BIR'


SQL> 


SY.
JDS
Дата: 14.10.2015 22:15:21
Если надо еще и форматирование, то проще сделать не на триггере, а процедурой где перед вставками делать нужные проверки с out-параметром, в который писать нужное сообщение.
ArtNick
Дата: 15.10.2015 10:01:07
JDS
Если надо еще и форматирование, то проще сделать не на триггере, а процедурой где перед вставками делать нужные проверки с out-параметром, в который писать нужное сообщение.

Проще сделать именно на триггере, только поле расширить до 4к.
см. СЫ
Дата: 15.10.2015 10:38:37
ArtNick
Проще сделать именно на триггере, только поле расширить до 4к.
осталось выяснить как именно реализовать эту простоту... и ограничить в юай ввод до этих 4к, чтобы проверять диапазон 1001-4000.