Почему этот SQL / DDL нарушает неправильное ограничение целостности? - PullRequest
0 голосов
/ 17 февраля 2020

Итак, это показывает мне, что первая вставка не работает с IC4, но это должно быть хорошо для go, что касается IC2. IC2 заявляет, что «DB guru» должен быть выше 200 - это первая запись!

Например, вы увидите, что первая запись в списке вставок ниже:

INSERT INTO Employee VALUES (10, 'Gray', 'DB guru', 240);

Но это не так IC4 ... почему?!

Как сделать Я указываю, что CONSTRAINT должен применяться только к определенному категориальному значению, как я пытаюсь здесь? Я скучаю по важному понятию относительно того, как реализуется CHECK? Я действительно новичок в SQL и пытаюсь обернуть голову вокруг этого:

SPOOL ddl.out
SET ECHO ON

--
-- IMPORTANT: use the names IC1, IC2, etc. as given below.
-- --------------------------------------------------------------------
/*The following DROP command is inserted for convenience so that if you need to recompile
your code, it will drop the table (if it already exists).
*/
DROP TABLE Employee CASCADE CONSTRAINTS;
DROP TABLE Dependent CASCADE CONSTRAINTS;
--
CREATE TABLE Employee
(
id INTEGER PRIMARY KEY,
name CHAR(10) NOT NULL,
rank CHAR(10) NOT NULL,
salary INTEGER NOT NULL,
/*
IC1: The rank is one of: 'DB guru', 'DB expert', or 'DB rookie'
*/
CONSTRAINT IC1 CHECK (rank IN ('DB guru', 'DB expert', 'DB rookie')),
/*
IC2: The salary of a 'DB guru' is above 200.
*/
CONSTRAINT IC2 CHECK (rank != 'DB guru' OR salary > 200),
/*
IC3: The salary of a 'DB expert' is between 80 and 220 (inclusive).
*/
CONSTRAINT IC3 CHECK (rank != 'DB expert' OR (salary >= 80 AND salary <= 220 )),
/*
IC4: The salary of a 'DB rookie' is less than 100.
*/
CONSTRAINT IC4 CHECK (rank != 'DB rookie' OR salary < 100)
);
--
--
CREATE TABLE Dependent
(
empID INTEGER,
dependentName CHAR(20) NOT NULL,
relationship CHAR(20) NOT NULL,
PRIMARY KEY (empID, dependentName),
/*
IC5: empID must refer to an employee in the company. Also:
if an employee is deleted then his/her dependents must be deleted.
IMPORTANT: DO NOT declare this IC as DEFERRABLE.
*/
CONSTRAINT IC5 FOREIGN KEY (empID) REFERENCES Employee(id)
          ON DELETE CASCADE
);
--
-- ----------------------------------------------------------------
-- TESTING THE SCHEMA
-- ----------------------------------------------------------------
INSERT INTO Employee VALUES (10, 'Gray', 'DB guru', 240);
INSERT INTO Employee VALUES (20, 'Garland', 'DB guru', 190);
INSERT INTO Employee VALUES (30, 'Edison', 'DB expert', 210);
INSERT INTO Employee VALUES (40, 'Eckerd', 'DB expert', 70);
INSERT INTO Employee VALUES (50, 'Roberts', 'DB rookie', 110);
INSERT INTO Employee VALUES (60, 'Rush', 'DB rookie', 90);
SELECT * from Employee;
-- ----------------------------------------------------------------
INSERT INTO Dependent VALUES (10, 'Grace', 'daughter');
INSERT INTO Dependent VALUES (10, 'George', 'son');
INSERT INTO Dependent VALUES (60, 'Reba', 'daughter');
INSERT INTO Dependent VALUES (15, 'Dustin', 'son');
SELECT * FROM Dependent;
--
DELETE FROM Employee WHERE id = 10;
SELECT * From Employee;
SELECT * FROM Dependent;
--
SET ECHO OFF
SPOOL OFF


отредактировано: чтобы показать рабочее решение на основе правильного ответа, выбранного ниже.

Ответы [ 2 ]

2 голосов
/ 17 февраля 2020

Я сомневаюсь, что вы можете сделать ограничения взаимоисключающими. Это может помочь вам:

CHECK ((rank = 'DB guru' AND salary > 200) or
       (rank = 'DB expert' AND salary >= 80 AND salary <=220 ) or
        ....

Редактировать: Кроме того, ваша логика IC4 CHECK CONSTRAINT c неверна, она должна быть:

/*
IC4: The salary of a 'DB rookie' is less than 100.
*/
CONSTRAINT IC4 CHECK (rank = 'DB rookie' AND salary < 100)
);

вместо:

/*
IC4: The salary of a 'DB rookie' is less than 100.
*/
CONSTRAINT IC4 CHECK (rank = 'DB rookie' AND salary >= 100)
);

, что делает консолидированное условие следующим образом:

CHECK ((rank = 'DB guru' AND salary > 200) or
       (rank = 'DB expert' AND salary >= 80 AND salary <=220 ) or
       (rank = 'DB rookie' AND salary < 100))
0 голосов
/ 17 февраля 2020

Логическое значение A->B выражается как NOT A OR B. Например

/*
IC2: The salary of a 'DB guru' is above 200.
*/
CONSTRAINT IC2 CHECK (rank != 'DB guru' OR salary > 200),
...