0

我想添加一个检查约束,以确保没有人可以在家庭表中输入多个配偶。我正在尝试使用自定义定义的函数。我正在做这样的事情:

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是候选代码,Relationship是存储关系类型的列。

在这里我知道我们不能在检查约束中使用用户定义的函数,那么我有没有其他方法可以在 oracle 中完成这个?

提前致谢。

4

2 回答 2

1

由于 Oracle 数据库的内部架构,我们不能在检查约束中使用函数:编译函数和验证约束是不同的关注点。

也许您正在寻找的是一个 SQL 断言。Oracle (尚)不支持这些,但请在另一个线程中阅读此答案,该线程解释了如何使用物化视图实现解决方法。

但是,您可能只需要一个基于函数的索引。我假设 PMT_TRN_FAMILY 实现了某种形式的有向图。所以M_CODE -> RELATIONS -> N_CODE可以用来表示MIKKI is SPOUSE of NIKKIMO 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)
/

这是一个 SQL Fiddle 演示


如果这不能解决您的问题,请编辑您的问题以包含更多详细信息,例如表结构和一些示例数据。

于 2018-04-12T07:23:53.680 回答
0

猜测你的表结构:

SQL小提琴

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 |

然后有多个父母/孩子(甚至有多个非配偶关系的人),但只有一个配偶。

查询 2

INSERT INTO PMT_TRN_FAMILY ( M_CODE, RELATIONS, RELATED_TO )
  VALUES ( 1, 'SPOUSE', 7 )

结果

尝试添加第二个配偶,然后您会收到“一个配偶被侵犯”的错误:

ORA-00001: unique constraint (USER_4_2700A6.FAMILY__ONE_SPOUSE__U) violated
于 2018-04-12T08:17:21.153 回答