Oracle超类子类实体生成DDL缺少Discriminator Column错误如何解决
错误原因
该报错是支持弧(Arc)外键约束的数据库建模工具(如Oracle SQL Developer Data Modeler)的通用校验规则:当你设置多个子类表通过外键关联同一个超类表的主键时,必须在超类表中设置鉴别器列,用来标记每一行记录所属的子类类型,避免同一条超类记录同时关联多个子类的逻辑错误。
解决步骤
- 第一步:在超类表
tb_transaksi中新增鉴别器列(比如命名为tipe_transaksi),同时补充你初始定义的tgl_transaksi属性,该列的取值范围固定为你设置的子类标识(比如'CASH'对应现金交易、'DEBIT'对应借记卡交易、'CREDIT'对应信用卡交易)。 - 第二步:可以给每个子类表新增检查约束,确保插入的记录类型和鉴别器标识匹配,也可以直接让建模工具根据新增的鉴别器列自动生成弧约束触发器。
修正后的完整DDL示例
-- 1. 创建超类交易表,新增鉴别器列和缺失的超类属性 CREATE TABLE tb_transaksi ( id_transaksi NUMBER(10, 2) NOT NULL, tgl_transaksi DATE NOT NULL, tipe_transaksi VARCHAR2(10) NOT NULL, -- 新增鉴别器列 CONSTRAINT ck_tipe_transaksi CHECK (tipe_transaksi IN ('CASH', 'DEBIT', 'CREDIT')) -- 限定子类取值范围 ); ALTER TABLE tb_transaksi ADD CONSTRAINT tb_transaksi_pk PRIMARY KEY (id_transaksi); -- 2. 创建现金子类表 CREATE TABLE cash ( id_transaksi NUMBER(10, 2) NOT NULL, nominal NUMBER(10, 2) NOT NULL ); ALTER TABLE cash ADD CONSTRAINT cash_pk PRIMARY KEY (id_transaksi); ALTER TABLE cash ADD CONSTRAINT cash_tb_transaksi_fk FOREIGN KEY (id_transaksi) REFERENCES tb_transaksi (id_transaksi); -- 可选检查约束,确保记录类型匹配,也可由工具自动生成触发器实现 ALTER TABLE cash ADD CONSTRAINT cash_tipe_check CHECK ( EXISTS (SELECT 1 FROM tb_transaksi t WHERE t.id_transaksi = cash.id_transaksi AND t.tipe_transaksi = 'CASH') ); -- 3. 创建借记卡子类表 CREATE TABLE debit_card ( id_transaksi NUMBER(10, 2) NOT NULL, no_kartu VARCHAR2(16) NOT NULL ); ALTER TABLE debit_card ADD CONSTRAINT debit_card_pk PRIMARY KEY (id_transaksi); ALTER TABLE debit_card ADD CONSTRAINT debit_tb_transaksi_fk FOREIGN KEY (id_transaksi) REFERENCES tb_transaksi (id_transaksi); ALTER TABLE debit_card ADD CONSTRAINT debit_tipe_check CHECK ( EXISTS (SELECT 1 FROM tb_transaksi t WHERE t.id_transaksi = debit_card.id_transaksi AND t.tipe_transaksi = 'DEBIT') ); -- 4. 创建信用卡子类表 CREATE TABLE credit_card ( id_transaksi NUMBER(10, 2) NOT NULL, persen_bunga NUMBER(5,2) NOT NULL ); ALTER TABLE credit_card ADD CONSTRAINT credit_card_pk PRIMARY KEY (id_transaksi); ALTER TABLE credit_card ADD CONSTRAINT credit_tb_transaksi_fk FOREIGN KEY (id_transaksi) REFERENCES tb_transaksi (id_transaksi); ALTER TABLE credit_card ADD CONSTRAINT credit_tipe_check CHECK ( EXISTS (SELECT 1 FROM tb_transaksi t WHERE t.id_transaksi = credit_card.id_transaksi AND t.tipe_transaksi = 'CREDIT') );
修改完成后重新生成约束触发器就不会再报该错误。
内容的提问来源于stack exchange,提问作者Devy Putri Natalie
相关产品推荐
相关产品推荐

