如何将CHECK约束移入PL/SQL自定义someType类型体中?
把CHECK约束移入PL/SQL对象类型体的实现方法
好问题!要把表层面的CHECK约束逻辑封装到someType的类型体里,我们可以利用Oracle PL/SQL对象类型的构造函数重载来实现——在创建对象实例时就对tip的值做范围验证,从源头保证数据合法性,不用再在每个使用该类型的表中重复写CHECK约束。
具体实现步骤
1. 定义带构造函数的对象类型
首先在类型声明部分添加自定义构造函数的声明,然后在类型体中实现这个构造函数,加入范围验证逻辑:
CREATE OR REPLACE TYPE someType AS OBJECT ( tip NUMBER(13), -- 声明自定义构造函数,用于接收tip参数并做验证 CONSTRUCTOR FUNCTION someType(p_tip NUMBER) RETURN SELF AS RESULT ) FINAL; / CREATE TYPE BODY someType AS CONSTRUCTOR FUNCTION someType(p_tip NUMBER) RETURN SELF AS RESULT IS BEGIN -- 验证规则:必须是8到13位的正整数(10000000 ≤ tip ≤ 9999999999999) IF p_tip IS NULL THEN RAISE_APPLICATION_ERROR(-20002, 'tip不能为空值'); ELSIF p_tip < 10000000 OR p_tip > 9999999999999 THEN RAISE_APPLICATION_ERROR(-20001, 'tip必须是8到13位的正整数'); END IF; SELF.tip := p_tip; RETURN; END; END; /
2. 使用该类型创建表
现在创建表时就不需要再写CHECK约束了,因为类型本身已经会验证数据:
CREATE TABLE someTable( ID NUMBER PRIMARY KEY, PIN someType );
3. 测试验证
插入合法数据会成功:
INSERT INTO someTable VALUES(1, someType(12345678)); -- 8位,符合要求 INSERT INTO someTable VALUES(2, someType(9999999999999)); -- 13位,符合要求
插入非法数据会直接抛出自定义异常:
INSERT INTO someTable VALUES(3, someType(1234567)); -- 7位,触发-20001异常 INSERT INTO someTable VALUES(4, someType(NULL)); -- 空值,触发-20002异常
为什么这么做?
这种方式的好处是约束逻辑封装在类型内部,不管你在多少个表中使用someType,都不用重复写CHECK规则,只要类型的验证逻辑不变,所有使用该类型的地方都会自动遵循同一规则,维护起来更方便。
内容的提问来源于stack exchange,提问作者Jovan Jovanović
相关产品推荐
相关产品推荐

