在oracle中添加检查约束时调用用户定义函数时出错
Error in calling user defined function while adding check constraint in oracle
我想添加一个检查约束,以确保没有人可以在家庭中输入超过一个配偶 table。我正在尝试为此使用自定义函数。我正在做这样的事情:
ALTER TABLE PMT_TRN_FAMILY
ADD CONSTRAINT CK_SPOUSE
CHECK (GETSPOUSE(M_CODE) = 'True');
函数 GETSPOUSE 的定义在这里:
CREATE OR REPLACE FUNCTION GETSPOUSE (
P_M_CODE IN VARCHAR2
)
RETURN VARCHAR
IS Output VARCHAR2(5);
S_CNT NUMBER(2,0);
BEGIN
SELECT COUNT(1) INTO S_CNT FROM PMT_TRN_FAMILY WHERE M_CODE = P_M_CODE AND RELATIONS='Spouse';
IF S_CNT > 0 THEN
return ('False');
END IF;
return ('True');
END;
这里M_code是候选人的代码,Relations是存储关系类型的列。
Here 我知道我们不能在检查约束中使用用户定义的函数,那么我在 oracle 中有没有其他方法可以做到这一点?
提前致谢。
由于 Oracle 数据库的内部架构,我们不能在检查约束中使用函数:编译函数和验证约束是不同的问题。
也许您正在寻找的是 SQL 断言。 Oracle 尚不支持这些,但请阅读 this answer in another thread,其中解释了如何使用物化视图实施变通方法。
然而,您可能只需要一个 function-based 索引。我假设 PMT_TRN_FAMILY 实现了某种形式的有向图。这样就可以用M_CODE -> RELATIONS -> N_CODE
来表示MIKKI is SPOUSE of NIKKI
或者MO is FATHER of NOAH
。你可以在配偶之间实行一夫一妻制,同时仍然允许人们拥有多个孩子,如下所示:
create UNIQUE index only_one_spouse_fbi on PMT_TRN_FAMILY
(M_CODE
, case when RELATIONS='Spouse' then M_CODE else N_CODE end)
/
如果这不能解决您的问题,那么请 edit your question 包含更多详细信息,例如 table 结构和一些示例数据。
猜测你的 table 结构:
Oracle 11g R2 架构设置:
CREATE TABLE PEOPLE(
M_CODE NUMBER(20,0) CONSTRAINT PEOPLE__M_CODE__PK PRIMARY KEY
);
CREATE TABLE PMT_TRN_FAMILY (
M_CODE NUMBER(20,0) CONSTRAINT FAMILY__M_CODE__FK
REFERENCES PEOPLE ( M_CODE ),
RELATIONS VARCHAR2(20),
RELATED_TO NUMBER(20,0) CONSTRAINT FAMILY__RELATED_TO__FK
REFERENCES PEOPLE ( M_CODE )
);
然后我们可以修改它,添加一个唯一索引,检查每个 RELATIONS='SPOUSE'
是否只有一个 M_CODE
:
CREATE UNIQUE INDEX FAMILY__ONE_SPOUSE__U ON PMT_TRN_FAMILY (
CASE RELATIONS WHEN 'SPOUSE' THEN M_CODE END
);
正在插入一些测试数据:
INSERT INTO PEOPLE ( M_CODE )
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 7;
INSERT INTO PMT_TRN_FAMILY ( M_CODE, RELATIONS, RELATED_TO )
SELECT 1, 'SPOUSE', 2 FROM DUAL UNION ALL
SELECT 1, 'PARENT', 3 FROM DUAL UNION ALL
SELECT 1, 'PARENT', 4 FROM DUAL UNION ALL
SELECT 1, 'SIBLING', 4 FROM DUAL UNION ALL
SELECT 1, 'CHILD', 5 FROM DUAL UNION ALL
SELECT 1, 'CHILD', 6 FROM DUAL;
查询 1:
SELECT * FROM PMT_TRN_FAMILY
| M_CODE | RELATIONS | RELATED_TO |
|--------|-----------|------------|
| 1 | SPOUSE | 2 |
| 1 | PARENT | 3 |
| 1 | PARENT | 4 |
| 1 | SIBLING | 4 |
| 1 | CHILD | 5 |
| 1 | CHILD | 6 |
然后有多个parents/children(甚至有多个非配偶关系的人)但只有一个配偶。
查询 2:
INSERT INTO PMT_TRN_FAMILY ( M_CODE, RELATIONS, RELATED_TO )
VALUES ( 1, 'SPOUSE', 7 )
试图添加第二个配偶然后你得到一个错误 "one spouse violated":
ORA-00001: unique constraint (USER_4_2700A6.FAMILY__ONE_SPOUSE__U) violated
我想添加一个检查约束,以确保没有人可以在家庭中输入超过一个配偶 table。我正在尝试为此使用自定义函数。我正在做这样的事情:
ALTER TABLE PMT_TRN_FAMILY
ADD CONSTRAINT CK_SPOUSE
CHECK (GETSPOUSE(M_CODE) = 'True');
函数 GETSPOUSE 的定义在这里:
CREATE OR REPLACE FUNCTION GETSPOUSE (
P_M_CODE IN VARCHAR2
)
RETURN VARCHAR
IS Output VARCHAR2(5);
S_CNT NUMBER(2,0);
BEGIN
SELECT COUNT(1) INTO S_CNT FROM PMT_TRN_FAMILY WHERE M_CODE = P_M_CODE AND RELATIONS='Spouse';
IF S_CNT > 0 THEN
return ('False');
END IF;
return ('True');
END;
这里M_code是候选人的代码,Relations是存储关系类型的列。
Here 我知道我们不能在检查约束中使用用户定义的函数,那么我在 oracle 中有没有其他方法可以做到这一点?
提前致谢。
由于 Oracle 数据库的内部架构,我们不能在检查约束中使用函数:编译函数和验证约束是不同的问题。
也许您正在寻找的是 SQL 断言。 Oracle 尚不支持这些,但请阅读 this answer in another thread,其中解释了如何使用物化视图实施变通方法。
然而,您可能只需要一个 function-based 索引。我假设 PMT_TRN_FAMILY 实现了某种形式的有向图。这样就可以用M_CODE -> RELATIONS -> N_CODE
来表示MIKKI is SPOUSE of NIKKI
或者MO is FATHER of NOAH
。你可以在配偶之间实行一夫一妻制,同时仍然允许人们拥有多个孩子,如下所示:
create UNIQUE index only_one_spouse_fbi on PMT_TRN_FAMILY
(M_CODE
, case when RELATIONS='Spouse' then M_CODE else N_CODE end)
/
如果这不能解决您的问题,那么请 edit your question 包含更多详细信息,例如 table 结构和一些示例数据。
猜测你的 table 结构:
Oracle 11g R2 架构设置:
CREATE TABLE PEOPLE(
M_CODE NUMBER(20,0) CONSTRAINT PEOPLE__M_CODE__PK PRIMARY KEY
);
CREATE TABLE PMT_TRN_FAMILY (
M_CODE NUMBER(20,0) CONSTRAINT FAMILY__M_CODE__FK
REFERENCES PEOPLE ( M_CODE ),
RELATIONS VARCHAR2(20),
RELATED_TO NUMBER(20,0) CONSTRAINT FAMILY__RELATED_TO__FK
REFERENCES PEOPLE ( M_CODE )
);
然后我们可以修改它,添加一个唯一索引,检查每个 RELATIONS='SPOUSE'
是否只有一个 M_CODE
:
CREATE UNIQUE INDEX FAMILY__ONE_SPOUSE__U ON PMT_TRN_FAMILY (
CASE RELATIONS WHEN 'SPOUSE' THEN M_CODE END
);
正在插入一些测试数据:
INSERT INTO PEOPLE ( M_CODE )
SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 7;
INSERT INTO PMT_TRN_FAMILY ( M_CODE, RELATIONS, RELATED_TO )
SELECT 1, 'SPOUSE', 2 FROM DUAL UNION ALL
SELECT 1, 'PARENT', 3 FROM DUAL UNION ALL
SELECT 1, 'PARENT', 4 FROM DUAL UNION ALL
SELECT 1, 'SIBLING', 4 FROM DUAL UNION ALL
SELECT 1, 'CHILD', 5 FROM DUAL UNION ALL
SELECT 1, 'CHILD', 6 FROM DUAL;
查询 1:
SELECT * FROM PMT_TRN_FAMILY
| M_CODE | RELATIONS | RELATED_TO |
|--------|-----------|------------|
| 1 | SPOUSE | 2 |
| 1 | PARENT | 3 |
| 1 | PARENT | 4 |
| 1 | SIBLING | 4 |
| 1 | CHILD | 5 |
| 1 | CHILD | 6 |
然后有多个parents/children(甚至有多个非配偶关系的人)但只有一个配偶。
查询 2:
INSERT INTO PMT_TRN_FAMILY ( M_CODE, RELATIONS, RELATED_TO )
VALUES ( 1, 'SPOUSE', 7 )
试图添加第二个配偶然后你得到一个错误 "one spouse violated":
ORA-00001: unique constraint (USER_4_2700A6.FAMILY__ONE_SPOUSE__U) violated