Oracle 自动将一列设置为其他两列之和的约束

Oracle 自动将一列设置为其他两列之和的约束,oracle,Oracle,我想知道是否可以使用约束将一列的值设置为其他两列的总和。例如,给出以下表格: CREATE TABLE Room ( Room_Num NUMBER(3), Room_Band_ID NUMBER(2), Room_Type_ID NUMBER(2), Room_Price NUMBER(4), PRIMARY KEY (Room_Num), FOREIGN KEY(Room_Band_ID) REFERENCES Room_Band(Room_Band_ID), FOREIGN KEY(Roo

我想知道是否可以使用约束将一列的值设置为其他两列的总和。例如,给出以下表格:

CREATE TABLE Room (
Room_Num NUMBER(3),
Room_Band_ID NUMBER(2),
Room_Type_ID NUMBER(2),
Room_Price NUMBER(4),
PRIMARY KEY (Room_Num),
FOREIGN KEY(Room_Band_ID)
REFERENCES Room_Band(Room_Band_ID),
FOREIGN KEY(Room_Type_ID)
REFERENCES Room_Type(Room_Type_ID)
);


CREATE TABLE Booking (
Booking_ID NUMBER(10) NOT NULL,
GuestID NUMBER(4) NOT NULL,
StaffID NUMBER(2) NOT NULL,
Payment_ID NUMBER(4) NOT NULL,
Room_Num NUMBER(3) NOT NULL,
CheckInDate DATE NOT NULL,
CheckOutDate DATE NOT NULL,
Booking NUMBER(2) NOT NULL,
Price NUMBER(4),
PRIMARY KEY (Booking_ID),
FOREIGN KEY(GuestID)
REFERENCES Guest(GuestID),
FOREIGN KEY(StaffID)
REFERENCES Staff(StaffID),
FOREIGN KEY(Payment_ID)
REFERENCES Payment(Payment_ID),
FOREIGN KEY(Room_Num)
REFERENCES Room(Room_Num)
);
我知道这样做是可能的:

   Constraint PriceIs CHECK (Booking.Price=(Room.Room_Price*
   (Booking.CheckOutDate - Booking.CheckInDate)));
是否还可以设置一个约束,不仅确保价格正确,还可以将价格自动计算到相关元组的price字段中

更新

因此,我尝试设置一个触发器,如下所示:

   CREATE OR REPLACE trigger PriceCompute
   AFTER INSERT ON Booking
   FOR each row
   BEGIN
   UPDATE Booking
   SET 
   SELECT (Room.Room_Price*(Booking.CheckOutDate - Booking.CheckInDate))
   INTO
   Booking.Price
   FROM Booking
   JOIN ROOM ON Booking.Room_Num = Room.Room_Num
   END;
   /
但我发现了以下错误:


任何人都能看到我在这里误入歧途的地方,因为这超出了我的理解。

我想你必须在两张桌子上都设置一个触发器,因为每当房间的价格值改变或结账/入住日期改变时,它都会从你的计算中更新PriceIs字段


如果您不需要将计算部分存储在实际字段中,则始终可以创建一个视图,以便在查看该视图时对其进行计算。

我认为您必须在两个表上设置触发器,以便在房间的价格值更改或结账/入住日期更改时,它将根据您的计算更新PriceIs字段


如果您不需要将计算部分存储在实际字段中,则始终可以创建一个视图,以便在查看该视图时对其进行计算。

我认为您必须在两个表上设置触发器,以便在房间的价格值更改或结账/入住日期更改时,它将根据您的计算更新PriceIs字段


如果您不需要将计算部分存储在实际字段中,则始终可以创建一个视图,以便在查看该视图时对其进行计算。

我认为您必须在两个表上设置触发器,以便在房间的价格值更改或结账/入住日期更改时,它将根据您的计算更新PriceIs字段


如果不需要将计算部分存储在实际字段中,则始终可以创建一个视图,在查看该视图时对其进行计算。

是的,可以。这是你的选择。按我个人喜好的顺序列出:

  • 您可以拥有一个没有此列的表。并创建一个将动态计算此列的视图

  • 您可以使用oracle虚拟列

    create table  Room (
    ...
    price     NUMBER GENERATED ALWAYS AS (room_price*(checkOut-checkIn)) VIRTUAL,
    ...)
    
  • 您可以使用实际列(与2相同,每个Dave Costa):

  • 您可以编写触发器来填充它(如Mat M建议的那样)

  • 您可以编写存储过程,但在这种情况下,这样做太过分了


  • 是的,你可以。这是你的选择。按我个人喜好的顺序列出:

  • 您可以拥有一个没有此列的表。并创建一个将动态计算此列的视图

  • 您可以使用oracle虚拟列

    create table  Room (
    ...
    price     NUMBER GENERATED ALWAYS AS (room_price*(checkOut-checkIn)) VIRTUAL,
    ...)
    
  • 您可以使用实际列(与2相同,每个Dave Costa):

  • 您可以编写触发器来填充它(如Mat M建议的那样)

  • 您可以编写存储过程,但在这种情况下,这样做太过分了


  • 是的,你可以。这是你的选择。按我个人喜好的顺序列出:

  • 您可以拥有一个没有此列的表。并创建一个将动态计算此列的视图

  • 您可以使用oracle虚拟列

    create table  Room (
    ...
    price     NUMBER GENERATED ALWAYS AS (room_price*(checkOut-checkIn)) VIRTUAL,
    ...)
    
  • 您可以使用实际列(与2相同,每个Dave Costa):

  • 您可以编写触发器来填充它(如Mat M建议的那样)

  • 您可以编写存储过程,但在这种情况下,这样做太过分了


  • 是的,你可以。这是你的选择。按我个人喜好的顺序列出:

  • 您可以拥有一个没有此列的表。并创建一个将动态计算此列的视图

  • 您可以使用oracle虚拟列

    create table  Room (
    ...
    price     NUMBER GENERATED ALWAYS AS (room_price*(checkOut-checkIn)) VIRTUAL,
    ...)
    
  • 您可以使用实际列(与2相同,每个Dave Costa):

  • 您可以编写触发器来填充它(如Mat M建议的那样)

  • 您可以编写存储过程,但在这种情况下,这样做太过分了


  • 我认为更好的解决方案是使用动态计算值的视图。但是关于创建触发器的尝试,您应该使用
    :new.
    来引用插入到
    预订
    表中的值。您不需要对该表执行更新和查询来获取或修改正在插入的行中的值*。您只需将它们称为变量。因此,您可能希望执行以下操作:

    SELECT (Room.Room_Price*(:new.CheckOutDate - :new.CheckInDate))
       INTO
       :new.Price
       FROM ROOM WHERE :new.Room_Num = Room.Room_Num
    

    *事实上,您不能对其修改首先调用触发器的表执行查询或更新。如果触发器实际编译并运行,则会出现臭名昭著的“mutating table”错误。

    我认为更好的解决方案是使用动态计算值的视图。但是关于创建触发器的尝试,您应该使用
    :new.
    来引用插入到
    预订
    表中的值。您不需要对该表执行更新和查询来获取或修改正在插入的行中的值*。您只需将它们称为变量。因此,您可能希望执行以下操作:

    SELECT (Room.Room_Price*(:new.CheckOutDate - :new.CheckInDate))
       INTO
       :new.Price
       FROM ROOM WHERE :new.Room_Num = Room.Room_Num
    

    *事实上,您不能对其修改首先调用触发器的表执行查询或更新。如果触发器实际编译并运行,则会出现臭名昭著的“mutating table”错误。

    我认为更好的解决方案是使用动态计算值的视图。但是关于创建触发器的尝试,您应该使用
    :new.
    来引用插入到
    预订
    表中的值。您不需要对该表执行更新和查询来获取或修改正在插入的行中的值*。您只需将它们称为变量。因此,您可能希望执行以下操作:

    SELECT (Room.Room_Price*(:new.CheckOutDate - :new.CheckInDate))
       INTO
       :new.Price
       FROM ROOM WHERE :new.Room_Num = Room.Room_Num
    
    *事实上,您不能对其修改在中调用触发器的表执行查询或更新