我有2个模式/表格如图所示:
CREATE TABLE schema1.code_tbl
( code CHAR(6) PRIMARY KEY,
description CHAR(30)
);
CREATE TABLE schema2.record_tbl
( rec_id VARCHAR(10) PRIMARY KEY,
curr_code VARCHAR(6),
remarks VARCHAR(30)
);
我需要从curr_code
中的RECORD_TBL
到code
CODE_TBL
创建一个外键引用。
ALTER TABLE schema2.record_tbl
ADD CONSTRAINT record_code_fk
FOREIGN KEY (curr_code)
REFERENCES schema1.code_tbl (code);
这显然给了我ORA-02267
(与引用列不兼容的列类型)错误。
我无法更改CODE_TBL
中的代码列,因为我不拥有或控制schema1。我无法更改curr_code
中的RECORD_TBL
列,因为它会破坏我的应用程序中的许多函数,因为我们没有考虑尾随空格。
是否有其他方法可以强制实现2列之间的参照完整性?
答案 0 :(得分:2)
所以情况就是这样。你有一个已经建立的现有表record_tbl
(显然,因为改变它“打破了许多功能”)。迟来有人决定在这个表上强制执行关系完整性,但是选择这样做引用不同模式中的表和不同数据类型的列。
Hmmmm。
您的选择是:
schema2
中构建实体化视图,从schema1.code_tbl
复制数据。至关重要的是,定义MView code
列匹配schema2.record_tbl.curr_code
的数据类型,即varchar2(6)。您现在可以对schema2.mv_code_tbl.code
强制执行外键。 注意: MView列中的数据将被格式化为CHAR,即带有尾随空格。答案 1 :(得分:2)
如果schema2在Oracle 11g及更高版本上,使用虚拟列可能会解决您的问题,但这会改变您尝试避免的表的结构。如果你可以管理它,这就是它的完成方式
SQL> CREATE TABLE code_tbl
2 ( code CHAR(6) PRIMARY KEY,
3 description CHAR(30)
4 );
Table created
SQL>
SQL> CREATE TABLE record_tbl
2 ( rec_id VARCHAR2(10) PRIMARY KEY,
3 curr_code VARCHAR2(6),
4 remarks VARCHAR2(30)
5 );
Table created
SQL> INSERT INTO code_tbl(code, description) VALUES ('ABC', 'Test Data');
1 row inserted
SQL> INSERT INTO record_tbl(rec_id, curr_code, remarks) VALUES ('1', 'ABC', 'Test Row');
1 row inserted
SQL> SELECT * FROM record_tbl;
REC_ID CURR_CODE REMARKS
---------- --------- ------------------------------
1 ABC Test Row
SQL> SELECT * FROM code_tbl;
CODE DESCRIPTION
------ ------------------------------
ABC Test Data
SQL> ALTER TABLE record_tbl ADD curr_code_v CHAR(6) AS (trim(curr_code));
Table altered
SQL> SELECT * FROM record_tbl;
REC_ID CURR_CODE REMARKS CURR_CODE_V
---------- --------- ------------------------------ -----------
1 ABC Test Row ABC
SQL>
SQL> ALTER TABLE record_tbl
2 ADD CONSTRAINT record_code_fk
3 FOREIGN KEY (curr_code_v)
4 REFERENCES code_tbl (CODE);
Table altered
SQL> INSERT INTO record_tbl(rec_id, curr_code, remarks) VALUES ('2', 'ABC', 'Test Row 2');
1 row inserted
SQL> INSERT INTO record_tbl(rec_id, curr_code, remarks) VALUES ('3', 'XYZ', 'Test Row 2');
INSERT INTO record_tbl(rec_id, curr_code, remarks) VALUES ('3', 'XYZ', 'Test Row 2')
ORA-02291: integrity constraint (USER_X.RECORD_CODE_FK) violated - parent key not found
以下是Tom Kyte关于虚拟列的文字: https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:676611400346196844
答案 2 :(得分:0)
您无法在不同类型列中创建关系。 为什么必须在数据库中创建关系?您只能使用代码连接表。