SQL - добавить проверку ограничения с помощью функции-члена объекта
Я использую Oracle 11g для создания своих запросов SQL.
Пока у меня есть объект:
CREATE OR REPLACE TYPE property_type AS OBJECT (
propertyNo NUMBER,
dateOfRegistration DATE, [etc..]
MEMBER FUNCTION date_of_registration_is_valid RETURN NUMBER
);
/
Который компилирует без проблем и имеет тело:
CREATE OR REPLACE TYPE BODY property_type AS
MEMBER FUNCTION date_of_registration_is_valid RETURN NUMBER IS
is_valid NUMBER;
BEGIN
IF (self.dateOfRegistration < SYSDATE) THEN
is_valid := 1;
ELSE
is_valid := 0;
END IF;
RETURN is_valid;
END;
END;
/
Который также компилируется и работает нормально, тогда я добираюсь до своего стола:
CREATE TABLE property_table OF property_type (
PRIMARY KEY (propertyNo),
CONSTRAINT property_not_null
CHECK (propertyNo IS NOT NULL),
CONSTRAINT property_reg_is_valid
CHECK (property_object.date_of_registration_is_valid() = 1)
) NESTED TABLE relates_to STORE AS relates_to_table;
/
Который я ожидаю, чтобы проверить функцию date_of_registration_is_valid(), чтобы увидеть, если она возвращает значение 1 (true). Я пробовал все виды альтернатив, таких как замена property_object
значение для self
, оставив пустым и т. д., но я получаю сообщение об ошибке. Для вышесказанного это ошибка:
Error report -
SQL Error: ORA-00904: "PROPERTY_OBJECT"."DATE_OF_REGISTRATION_IS_VALID": invalid identifier
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Итак, как я могу использовать функцию-член в качестве ограничения проверки?
1 ответ
Из документации проверочные ограничения не могут вызывать пользовательские функции, которые предположительно включают функции-члены.
Вы можете получить похожее поведение с помощью функции конструктора, которая вызывает исключение:
CREATE OR REPLACE TYPE property_type AS OBJECT (
propertyNo NUMBER,
dateOfRegistration DATE,
-- [etc ]
CONSTRUCTOR FUNCTION property_type (SELF IN OUT NOCOPY property_type,
propertyNo NUMBER, dateOfRegistration DATE /* [etc] */ )
RETURN SELF AS RESULT
);
/
CREATE OR REPLACE TYPE BODY property_type AS
CONSTRUCTOR FUNCTION property_type (SELF IN OUT NOCOPY property_type,
propertyNo NUMBER, dateOfRegistration DATE /* [etc */ )
RETURN SELF AS RESULT IS
BEGIN
IF dateOfRegistration < SYSDATE THEN
RAISE_APPLICATION_ERROR(-20001, 'Registration date before today');
END IF;
SELF.propertyNo := propertyNo;
SELF.dateOfRegistration := dateOfRegistration;
RETURN;
END;
END;
/
Тогда без ограничения проверки функции-члена (или вложенной таблицы, так как у моего упрощенного типа ее нет) и без явной проверки нуля и первичный ключ в том же столбце подразумевает, что в любом случае:
CREATE TABLE property_table OF property_type (
PRIMARY KEY (propertyNo)
);
/
Table property_table created.
Пара пробных вставок:
insert into property_table values (property_type(1, sysdate));
1 rows inserted.
insert into property_table values (property_type(2, sysdate - 1));
Error starting at line : 32 in command -
insert into property_table values (property_type(2, sysdate - 1))
Error report -
SQL Error: ORA-20001: Registration date before today
ORA-06512: at "STACKOVERFLOW.PROPERTY_TYPE", line 7
В зависимости от данных может потребоваться проверка trunc(sysdate)
так что сегодня полночь, а не текущее время.