Я создал следующие таблицы и ограничения, используя Oracle Live ;
- oak_Hotel ( ht_no , ht_name, ht_city)
- oak_Guest( gt_no , gt_name, gt_address)
- oak_Room ( rm_no, htrm_no , rm_type, rm_price)
- oak_Booking ( htbk_no, gtbbk_dateFrom , bk_dateto, rmbk_no)
Ограничения:
- rm_type в oak_room должны быть ограничены "Single", "Double" или "Family"
- bk_dateFrom и bk_dateto не должны быть меньше текущей даты (достигнутой путем реализации триггера)
- Наконец, первичные ключи и внешние ключи, где это уместно, показаны выше.
Для создания таблиц и ограничений используются следующие операторы SQL:
CREATE TABLE oak_Hotel (
ht_no int NOT NULL,
ht_name varchar(25),
ht_city varchar(25),
CONSTRAINTS PK_hotel PRIMARY KEY(ht_no)
);
CREATE TABLE oak_Guest (
gt_no int NOT NULL,
gt_name varchar(25),
gt_address varchar(25),
CONSTRAINTS PK_guest PRIMARY KEY(gt_no)
);
CREATE TABLE oak_Room (
rm_no int NOT NULL UNIQUE,
htrm_no int NOT NULL,
rm_type varchar(25),
rm_price NUMERIC(6, 2),
CONSTRAINTS PK_room PRIMARY KEY (rm_no, htrm_no),
CONSTRAINTS FK_guest FOREIGN KEY (htrm_no) REFERENCES
oak_Hotel(ht_no)
);
ALTER TABLE oak_Room
ADD CONSTRAINT CHK_Oak_room CHECK ((rm_type='Single' OR
rm_type='DOUBLE' OR rm_type='Family') AND (rm_price>=100
AND rm_type<=1000) AND (rm_no>=1 AND rm_no<=100));
CREATE TABLE oak_Booking (
htbk_no int NOT NULL,
gtbk_no int NOT NULL,
bk_dateFrom date NOT NULL,
bk_dateto date,
rmbk_no int,
CONSTRAINTS PK_booking PRIMARY KEY (htbk_no, gtbk_no, bk_dateFrom),
CONSTRAINTS FK_booking_htno FOREIGN KEY (htbk_no) REFERENCES oak_Hotel(ht_no),
CONSTRAINTS FK_booking_gtno FOREIGN KEY (gtbk_no) REFERENCES oak_Guest(gt_no),
CONSTRAINTS FK_booking_rmno FOREIGN KEY (rmbk_no) REFERENCES oak_Room(rm_no)
);
CREATE OR REPLACE TRIGGER trg_check_dates
BEFORE INSERT OR UPDATE ON oak_Booking
FOR EACH ROW
BEGIN
IF( :new.bk_dateFrom < SYSDATE )
THEN
RAISE_APPLICATION_ERROR( -20001,
'Invalid DA=ateFrom: CloseDate must be greater than the current date - value = ' || to_char( :new.bk_dateFrom, 'YYYY-MM-DD HH24:MI:SS' ) );
END IF;
IF( :new.bk_dateto <= SYSDATE )
THEN
RAISE_APPLICATION_ERROR( -20001,
'Invalid DA=ateFrom: CloseDate must be greater than the current date - value = ' || to_char( :new.bk_dateto, 'YYYY-MM-DD HH24:MI:SS' ) );
END IF;
END;
Ошибка появляется, когда я пытаюсь заполнить таблицу oak_room ORA-01722: invalid number ORA-06512: at "SYS.DBMS_SQL", line 1721
. Следующие две первые истории заполняются (oak_hotel, oak_guest).
-- Data Entry
-- ***** Hotel Table *****
INSERT INTO oak_Hotel
VALUES (1234, 'Oak Tree', 'Gaborone');
-- ***** Hotel Guest *****
INSERT INTO oak_Guest
VALUES (1001, 'Sherlock Holmes', '22 Bakers Street');
INSERT INTO oak_Guest
VALUES (1002, 'Donald Trump', 'Twitter Streets');
INSERT INTO oak_Guest
VALUES (1003, 'Iceberg Slim', 'These Streets');
INSERT INTO oak_Guest
VALUES (1004, 'Denise The Menace', '301 Childhood lane');
Ошибка появляется, когда я выполняю следующую инструкцию:
-- ****** Hotel Room ******
INSERT INTO oak_Room
VALUES (1, 1234, 'Single', 100.00);
ORA-01722: invalid number ORA-06512: at "SYS.DBMS_SQL", line 1721