这是一个非常初学的问题,但我的谷歌技能让我失望,我似乎无法在笔记中找到任何内容。
在我的任务中,我必须根据教授给出的标准创建几个约束。
我们有一个名为Employee的表。员工有一个等级(char),该等级可以是'DB Guru','DB expert'或'DB newokie'。他们也有工资(整数)。这种约束我很容易做到。
之后的约束是确保排名为“DB guru”的人的薪水高于200.
我很困惑,我如何检查等级的值是否为'DB guru',并检查工资是否高于200.这是检查我看不到的排名的代码找到该怎么做。
这是我到目前为止所尝试的:
IC2: The salary of a 'DB guru' is above 200.
*/
CONSTRAINT IC2 CHECK(rank IN('DB guru') AND salary > 200)),
这给了我错误: 第14行的错误: ORA-00922:缺少或无效选项
第14行是我发布的Cconstraint,所以我猜这是一个语法错误。
有人能告诉我一个比较这些值的正确语法示例吗?
提前感谢您的帮助。
编辑:这是整个Create语句,以及我对每个约束的尝试。
-- IMPORTANT: use the names IC1, IC2, etc. as given below.
-- --------------------------------------------------------------------
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'
*/
COnstraing IC1 CHECK(rank IN('DB guru', 'DB expert', 'DB rookie')),
IC2: The salary of a 'DB guru' is above 200.
*/
CONSTRAINT IC2 CHECK(rank IN('DB guru') AND salary > 200)),
/*
IC3: The salary of a 'DB expert' is between 80 and 220 (inclusive).
*/
CONSTRAINT IC3 CHECK(rank IN('DB expert) AND salary >= 80 AND salary <= 220),
/*
IC4: The salary of a 'DB rookie' is less than 100.
*/
CONSTRAINT IC4 CHECK(rank IN('DB rookie') AND salary < 100))
);
答案 0 :(得分:2)
再次考虑一下这张支票的内容:
CONSTRAINT IC2 CHECK(rank IN('DB guru') AND salary > 200))
这就是说,对于每个行,rank
必须完全等于'DB Guru'
,而salary
必须大于200.这是不你想要什么。你需要反过来思考 - 如果rank
是其他而不是'DB Guru'
,那么你不关心(在这个约束条件下)他们的薪水是多少。所以你真的想要:
CONSTRAINT IC2 CHECK(rank != 'DB guru' OR salary > 200)
最后你还有一个额外的)
(在第一个例子中计算()
,你会发现它们没有平衡)。您在IC4
的末尾有类似的错误。
@wildplasser的补充工具栏 - 正如我所说,我们的两个IC2
是等价的,使用了一点布尔逻辑:
NOT( zrank IN('DB guru') AND salary <= 200) --Your IC2
等于:
(NOT zrank IN ('DB guru')) OR (NOT salary <= 200) --De Morgan's law
等于:
(zrank != 'DB guru') OR (NOT salary <= 200) --Simplification of first
等于:
(zrank != 'DB guru') OR (salary > 200) --Simplification of second
等于:
zrank != 'DB guru' OR salary > 200 --Removal of brackets, my IC2
答案 1 :(得分:1)
-- --------------------------------------------------------------------
-- IMPORTANT: use the names IC1, IC2, etc. as given below.
-- --------------------------------------------------------------------
DROP TABLE Employee CASCADE ;
--
CREATE DOMAIN dbarank AS CHAR(10) CHECK (VALUE IN ('DB guru', 'DB expert', 'DB rookie') );
CREATE TABLE Employee
( id INTEGER PRIMARY KEY
, name CHAR(10) NOT NULL
, zrank dbarank NOT NULL -- "rank" is a reserved name
, salary INTEGER NOT NULL
-- IC2: The salary of a 'DB guru' is above 200.
, CONSTRAINT IC2 CHECK ( NOT( zrank IN('DB guru') AND salary <= 200))
-- IC3: The salary of a 'DB expert' is between 80 and 220 (inclusive).
, CONSTRAINT IC3 CHECK ( NOT (zrank IN ('DB expert') AND ( salary < 80 OR salary > 220)))
-- IC4: The salary of a 'DB rookie' is less than 100.
, CONSTRAINT IC4 CHECK ( NOT (zrank IN('DB rookie') AND salary >= 100))
);
INSERT INTO Employee(id,name,zrank,salary) VALUES(1, 'Pipo', 'Clown', 1);
INSERT INTO Employee(id,name,zrank,salary) VALUES(1, 'Lutser', 'DB rookie', 110);
INSERT INTO Employee(id,name,zrank,salary) VALUES(1, 'Prutser', 'DB rookie', 90);
注意:由于我使用了Postgres,因此语法略有不同。 Oracle确实有域,因此将IC1实现为域约束的“技巧”仍然有效。
结果:
CREATE DOMAIN
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "employee_pkey" for table "employee"
CREATE TABLE
ERROR: value for domain dbarank violates check constraint "dbarank_check"
ERROR: new row for relation "employee" violates check constraint "ic4"
INSERT 0 1
更新:修复NOT(AND / OR)内容,使约束成为独占。