1

这是一个非常初学者的问题,但我的谷歌技能让我失望了,我似乎在我的笔记中找不到任何东西。

在我的作业中,我必须根据教授给出的标准创建几个约束条件。

我们有一个名为 Employee 的表。员工有一个等级(字符),该等级可以是“DB Guru”、“DB 专家”或“DB rookie”。他们也有薪水(整数)。这个约束我很容易做到。

随之而来的限制是确保任何具有“DB guru”级别的人的薪水高于 200。

我很困惑如何检查 rank 的值是否为“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))
); 
4

2 回答 2

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)

最后你还有一个额外)的(计算()第一个例子中的 s,你会发现它们不平衡)。结尾处有类似的错误IC4


@wildplasser 的侧边栏 - 正如我所说,我们的两个IC2s 是等价的,使用一点布尔逻辑:

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
于 2012-10-17T12:20:41.340 回答
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) 的东西,使约束排他性。

于 2012-10-17T12:41:15.287 回答