1

これは非常に初歩的な質問ですが、Google のスキルが足りず、メモに何も見つからないようです。

私の課題では、教授から与えられた基準に基づいて、いくつかの制約を作成する必要があります。

Employee というテーブルがあります。従業員にはランク (文字) があり、そのランクは「DB Guru」、「DB エキスパート」、または「DB 新人」のいずれかです。また、給与 (整数) もあります。この制約は簡単に作成できました。

後に続く制約は、ランク「DB グル」を持つ人の給与が 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))
); 
4

2 に答える 2

2

もう一度、このチェックが言っていることを考えてみてください。

CONSTRAINT IC2 CHECK(rank IN('DB guru') AND salary > 200))

これは、すべての行について、rankと正確に等しく'DB Guru'salary200より大きくなければならないということです。それはあなたが望むものではありません。逆に考える必要があります-rank以外の場合'DB Guru'、(この制約では)彼らの給与が何であるかは気にしません。だからあなたは実際に欲しい:

CONSTRAINT IC2 CHECK(rank != 'DB guru' OR salary > 200)

また、最後に余分なものがあり)ました(最初の例でsを数えると、()バランスが取れていないことがわかります)。の終わりにも同様のエラーがありIC4ます。


@wildplasserのサイドバー-私が言ったように、2つ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
于 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 に答える