Если ограничение Oracle нарушено, установите значение по умолчанию? Как мне это сделать? - PullRequest
0 голосов
/ 29 апреля 2018

У меня проблемы с установкой значения по умолчанию в базе данных Oracle.

Я хочу установить значение по умолчанию для моего региона NW: region CHAR(2) DEFAULT ('NW'),

У меня также есть проверка ссылок, чтобы убедиться, что все значения в регионе состоят из 2 символов: CONSTRAINT check_region CHECK (region IN ('N', 'NW', 'NE', 'S', 'SE', 'SW', 'W', 'E')));

Однако я получаю эту ошибку, когда вставляю данные, которые не соответствуют моим ограничениям. У меня есть строка данных, которая имеет 'NULL' для значения, поэтому оно не должно быть вставлено ... но это должно по умолчанию значение по умолчанию NW ... правильно?

Error starting at line : 16 in command -
INSERT into acctmanager
 (amid, amfirst, amlast, amedate, amsal, amcomm, region) VALUES ('L500','MANDY','LOPEZ','01-OCT-09', 47000, 1500, 'NULL')
Error report -
ORA-02290: check constraint (SYS.CHECK_REGION) violated

Я понимаю, что ошибка должна появиться ... но должно ли значение не соответствовать значению, которое я определил в моей схеме для region? Я пытался посмотреть здесь , но я все еще получаю сообщение об ошибке при вставке.

Есть предложения?

Вот мой полный оператор создания таблицы:

DROP TABLE ACCTMANAGER CASCADE CONSTRAINTS;

CREATE TABLE acctmanager
(amid CHAR(4),
 amfirst VARCHAR2(12)  NOT NULL,
 amlast VARCHAR2(12)  NOT NULL,
 amedate DATE DEFAULT SYSDATE NOT NULL,
 amsal NUMBER(8,2),
 amcomm NUMBER(7,2),
 region CHAR(4) DEFAULT ('NW'),
  CONSTRAINT PK_acctmanager PRIMARY KEY (amid),
  CONSTRAINT check_region CHECK (region IN ('N', 'NW', 'NE', 'S', 'SE', 'SW', 'W', 'E')));

INSERT into acctmanager
 (amid, amfirst, amlast, amedate, amsal, amcomm, region) VALUES ('T500','NICK','TAYLOR','05-SEP-09', 42000, 3500, 'NE');
INSERT into acctmanager
 (amid, amfirst, amlast, amedate, amsal, amcomm, region) VALUES ('L500','MANDY','LOPEZ','01-OCT-09', 47000, 1500, 'NULL');
INSERT into acctmanager
 (amid, amfirst, amlast, amedate, amsal, amcomm, region) VALUES ('J500','SAMMIE','JONES','DEFAULT' , 39500, 2000, 'NW');

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Вы можете использовать select from dual вместо ключевого слова values. Это приводит nvl в игру.

Итак, вместо этого:

insert into table
(field1, field2, etc)
values
(value1, value2, etc)

сделать это:

insert into table
(field1, field2, etc)
select nvl(field1, default value1)
, nvl(field2, default value2)
, etc
from dual
0 голосов
/ 29 апреля 2018
VALUES ('L500','MANDY','LOPEZ','01-OCT-09', 47000, 1500, 'NULL')

Не 'NULL', а NULL (без одинарных кавычек).

[EDIT]

Вот пример триггера:

SQL> create table test
  2    (id      number,
  3     region  varchar2(2) default 'NW'
  4    );

Table created.

SQL> create or replace trigger trg_biu_test
  2    before insert or update on test
  3    for each row
  4  begin
  5    if :new.region not in ('N', 'NW', 'NE') then
  6       :new.region := 'NW';
  7    end if;
  8  end;
  9  /

Trigger created.

Тестирование: если имя REGION длиннее, чем VARCHAR2 (поскольку именно так объявлен столбец, вставка завершится неудачно независимо от триггера):

SQL> insert into test (id, region) values (1, 'what?');
insert into test (id, region) values (1, 'what?')
*
ERROR at line 1:
ORA-12899: value too large for column "SCOTT"."TEST"."REGION" (actual: 5, maximum: 2)

Короче (до 2 символов) будет в порядке:

SQL> insert into test (id, region) values (1, 'xx');

1 row created.

Вставка NULL в регион фактически вставит значение по умолчанию:

SQL> insert into test (id) values (2);

1 row created.

SQL>
SQL> select * From test;

        ID RE
---------- --
         1 NW
         2 NW

SQL>

[РЕДАКТИРОВАТЬ # 2: ключевое слово DEFAULT]

Еще одним вариантом является использование ключевого слова DEFAULT, например

SQL> insert into test (id, region) values (3, default);

1 row created.

SQL> select * From test where id = 3;

        ID RE
---------- --
         3 NW

Спасибо Вернфриду за комментарий.

...