检查约束违例错误,但未指定列

时间:2017-12-12 01:21:50

标签: sql oracle

我已经制作了下表:

CREATE TABLE Employee (
Employee_ID      NUMBER(10)    NOT NULL PRIMARY KEY,
Company_ID       NUMBER(10)    NOT NULL REFERENCES 
Penrhyn_Jet_Charter(Company_ID),
First_Name       VARCHAR2(255) NOT NULL,
Last_Name        VARCHAR2(255) NOT NULL,
Address          VARCHAR2(300) NOT NULL,

Email_Address    VARCHAR2(255) NOT NULL UNIQUE CHECK (Email_Address                  
LIKE '%_@__%.__%'),
Telephone_Number NUMBER(15)    NOT NULL CHECK (Telephone_Number > 0),
Mobile_Number    NUMBER(15)    NOT NULL UNIQUE CHECK (Mobile_Number>0), 
Date_Of_Birth    DATE          NOT NULL,
Gender           CHAR(1)       NOT NULL, CHECK (Gender = 'M' OR Gender 
= 'F'),

NI_Number        VARCHAR2(10)  NOT NULL UNIQUE CHECK (NI_Number Like 
'[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]'),
Job_Description  VARCHAR2(255) NOT NULL,
Annual_Salary    NUMBER(10)    NOT NULL CHECK (Annual_Salary > 0)
);

CREATE OR REPLACE TRIGGER Check_Date_Of_Birth
BEFORE INSERT OR UPDATE ON Employee
FOR EACH ROW
BEGIN
IF( :NEW.Date_Of_Birth < DATE '1900-01-01' OR 
:NEW.Date_Of_Birth > SYSDATE )
THEN
RAISE_APPLICATION_ERROR ( -20001, 
'Date of birth must be later than Jan 1, 1900 and earlier than today' 
);
END IF; 
END;

创建上表时没有错误。

但是当我试图填充表格时,它给了我这个错误:

  

插入员工价值观(1,1,&#39; Gary&#39;,&#39; Turner&#39;,&#39; 5 Orpington Street,Crawley,CR18 25J&#39;,   &#39; garyturner@mail.com',087948743,938468364,TO_DATE(&#39; 1985-05-06&#39;,&#39; YYYY-MM-DD&#39;),   &#39; F&#39;,&#39; aa111111a&#39;,&#39; Pilot&#39;,12500)   错误报告 -   ORA-02290:违反检查约束(K1651915.SYS_C0074079)

这是我的插入声明:

INSERT INTO Employee VALUES (1, 1, 'Gary', 'Turner', '5 Orpington 
Street, Crawley, CR18 25J',
'garyturner@mail.com', 087948743, 938468364, TO_DATE('1985-05-
06','YYYY-
MM-DD'),
'F', 'aa111111a', 'Pilot', 12500);

它没有指定它违反了哪个列的检查约束,所以我很困惑。

我做错了什么,如何解决?

1 个答案:

答案 0 :(得分:1)

简而言之,您的CHECK CONSTRAINT使用REGEXP检查,但实际上是在进行WHERE检查。

如果要在检查约束中使用正则表达式,则需要使用REGEXP_LIKE:

CONSTRAINT ck_ni_number
  CHECK (REGEXP_LIKE(ni_number, '[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]'))

此代码将在CREATE TABLE语句的末尾。我已经这样声明了(caleld和out-of-line约束)因为它允许你命名约束并且很容易看到错误与ni_number有关。

您的整个CREATE TABLE语句将如下所示:

CREATE TABLE Employee (
Employee_ID      NUMBER(10)    NOT NULL PRIMARY KEY,
Company_ID       NUMBER(10)    NOT NULL REFERENCES Penrhyn_Jet_Charter(Company_ID),
First_Name       VARCHAR2(255) NOT NULL,
Last_Name        VARCHAR2(255) NOT NULL,
Address          VARCHAR2(300) NOT NULL,
Email_Address    VARCHAR2(255) NOT NULL UNIQUE,
Telephone_Number NUMBER(15)    NOT NULL,
Mobile_Number    NUMBER(15)    NOT NULL UNIQUE,
Date_Of_Birth    DATE          NOT NULL,
Gender           CHAR(1)       NOT NULL, 
NI_Number        VARCHAR2(10)  NOT NULL UNIQUE,
Job_Description  VARCHAR2(255) NOT NULL,
Annual_Salary    NUMBER(10)    NOT NULL,
CONSTRAINT ck_ni_number 
  CHECK (REGEXP_LIKE(ni_number, '[a-z][a-z][0-9][0-9][0-9][0-9][0-9][0-9][a-z]')),
CONSTRAINT ck_tel_num CHECK (Telephone_Number > 0),
CONSTRAINT ck_email CHECK (Email_Address LIKE '%_@__%.__%'),
CONSTRAINT ck_mob_num CHECK (Mobile_Number > 0),
CONSTRAINT ck_gender CHECK (Gender = 'M' OR Gender = 'F'),
CONSTRAINT ck_an_salary CHECK (Annual_Salary > 0)
);

另外,我建议在INSERT语句中指定列。如果没有指定列名,Oracle将假定您的值的顺序,这是无法保证的。

要做到这一点:

INSERT INTO Employee
  (employee_id, company_id, first_name, last_name, address, 
  email_address, telephone_number, mobile_number, date_of_birth, 
  gender, ni_number, job_description, annual_salary)
VALUES (1, 1, 'Gary', 'Turner', 
  '5 Orpington Street, Crawley, CR18 25J',
  'garyturner@mail.com', 087948743, 938468364, 
  TO_DATE('1985-05-06','YYYY-MM-DD'),
  'F', 'aa111111a', 'Pilot', 12500);

我要提出的另一个建议是,您可能需要考虑将phone_number和mobile_number字段设为VARCHAR2而不是数字。这是因为电话号码可以从0开始,并且电话号码没有对它们执行任何算术运算。但这超出了你的问题的范围!

希望能解决您的问题。