约束表中的行数,按另一个表中的值

时间:2012-12-04 10:11:50

标签: sql oracle sqlplus

我有一张名为ward的桌子(与医院打交道):

Create table ward(
    Wno varchar(15) Primary Key,
    Name varchar(20) Not Null,
    Number_of_beds integer Not Null
);

为患者提供一张桌子:

Create table patient(
    Pid varchar(15) Primary Key,
    Name varchar(20) Not Null,
    Address varchar(50) Not Null,
    Date_of_birth date Not Null
 );

我需要以某种方式约束患者,以便如果患者被分配到特定病房,那么患者的数量不能超过病房中的病床数量。 我想把Wno作为外键添加到患者台上,但是不知道从那里去哪里。

1 个答案:

答案 0 :(得分:2)

您可以将以下外键添加到患者表中。道歉此查询是在MYSQL中。我注意到你需要Oracle。但是逻辑类似:)语法需要改变。

Create table ward(
    Wno varchar(15) Not null Primary Key,
    Name varchar(20) Not Null,
    Number_of_beds integer Not Null
);

为患者提供一张桌子:

Create table patient(
    Pid varchar(15) Primary Key,
    Name varchar(20) Not Null,
    Address varchar(50) Not Null,
    Date_of_birth date Not Null,
    WardNo varchar(15),
    foreign key (wardno) references ward (wno)  ' -- adds the foreign key relation
 );

为了检查病房是否已满,您可以insertupdate trigger

可以通过以下查询获得免费床位数:

SELECT p.wardno, (w.number_of_beds - count(pid)) as freebeds
from patient as p
left join ward as w
on p.wardno = w.wno
group by wardno

现在我们创建一个触发器来检查是否有病人进入病房,其中freebed count = 0。

已更新至Oracle版

 CREATE OR REPLACE TRIGGER FreeBedsWardTrigger
       BEFORE UPDATE OR INSERT
       ON patient
       FOR EACH ROW
    DECLARE
       max_beds    INTEGER;    -- max number of beds for the ward
       used_beds   INTEGER;    -- used beds for the ward
    BEGIN
       SELECT   COUNT (pid)
         INTO   used_beds
         FROM   patient
        WHERE   wardno = :NEW.wardno;

       SELECT   number_of_beds
         INTO   max_beds
         FROM   ward
        WHERE   wno = :NEW.wardno;

       IF (max_beds - used_beds) > 0
       THEN
          RETURN;
       ELSE
          RAISE_APPLICATION_ERROR (-100100,
                                   'No more beds available in this ward.');
       END IF;
    END;