我查看了互联网,他们的解决方案不会解决我的问题,因此我在这里寻求帮助来检查我的编码是否存在错误。
我想创建一个由其他源表填充的临时表,然后将其实现到事实表中。我已检查数据类型和参数是否匹配或键的顺序但是它仍然给我错误
" ORA-02291:违反了完整性约束(SYSTEM.SYS_C007167) - 未找到父密钥"
事实表:
0
临时表:
CREATE TABLE DW_ITEMS7364 (
DW_ID int not null,
ManID char(5),
WHID char(5),
STKID char(5),
Profit number,
CONSTRAINT DW_ID PRIMARY KEY (DW_ID),
FOREIGN KEY(ManID) REFERENCES DW_MANUFACTURER7364,
FOREIGN KEY(WHID) REFERENCES DW_WAREHOUSE7364,
FOREIGN KEY(StkID) REFERENCES DW_STOCKITEM7364);
CREATE SEQUENCE seq_items7364 START WITH 101 increment by 1;
CREATE TRIGGER trg_items7364 BEFORE INSERT OR UPDATE ON DW_ITEMS7364
FOR EACH ROW
BEGIN
SELECT seq_items7364.NEXTVAL
INTO :new.DW_ID
FROM dual;
END;
这些是我的源表:
CREATE TABLE TEMP_TAB7364 AS( SELECT m.ManID, w.WHID, s.STKID, (s.SellingPrice-s.PurchasePrice) AS "Profit"
FROM MANUFACTURER7364 m LEFT OUTER JOIN STOCKITEM7364 s ON s.ManID = m.ManID
RIGHT OUTER JOIN WAREHOUSE7364 w on s.WHID = w.WHID WHERE s.SELLINGPRICE IS NOT NULL AND s.PURCHASEPRICE IS NOT NULL
);
答案 0 :(得分:1)
据我所知,没有您发布的内容会引发该错误。
另外一个缺点是您选择创建外键约束的方式。如果您没有为其命名,Oracle会自行分配名称,它看起来就像您发布它的方式:SYSTEM.SYS_C007167
。
SQL> create table test
2 (id_dept number,
3 id_emp number,
4 foreign key (id_dept) references dept (deptno),
5 foreign key (id_emp) references emp (empno));
Table created.
SQL> select constraint_name from user_constraints where table_name = 'TEST';
CONSTRAINT_NAME
------------------------------
SYS_C008172
SYS_C008173
SQL>
当其中一个失败时,查看其名称不知道出了什么问题,除非您再进行一些调查:
SQL> select column_name from user_cons_columns where constraint_name = 'SYS_C008173';
COLUMN_NAME
-----------------------
ID_EMP
SQL>
但是,如果您命名约束,则更简单:
SQL> create table test
2 (id_dept number,
3 id_emp number,
4 constraint fk_test_dept foreign key (id_dept) references dept (deptno),
5 constraint fk_test_emp foreign key (id_emp) references emp (empno));
Table created.
SQL> select constraint_name from user_constraints where table_name = 'TEST';
CONSTRAINT_NAME
------------------------------
FK_TEST_DEPT
FK_TEST_EMP
SQL>
另一个主要的缺点是注意点是在点前写的,这里是:SYSTEM.SYS_C007167
。是的,那将是SYSTEM
。不久,不要这样做。离开SYS和SYSTEM;它们很强大,它们很特别。如果您(非)故意做有害的事情,为什么要冒破坏数据库的风险?创建另一个用户,授予所需权限并在该模式中工作。
如果我理解正确,一旦你创建了 temp 表(TEMP_TAB7364
),它的内容就会转移到DW_ITEMS7364
并且 - 这样做 - 你遇到错误。
如果是这样,那么 temp 表的目的是什么?直接插入目标表并节省资源。它会失败吗?当然它会,除非你改变查询。怎么样?我不知道 - 确保不插入用于强制参照完整性的三个表中任何一个中不存在的值。
虽然,因为你已经有 temp 表,如果它不是太大,一个(相对)快速&找出哪一行负责错误的脏方法可以通过循环找到,例如
begin
for cur_r in (select col1, col2, ... from temp_table) loop
begin
insert into target (col1, col2, ...)
values (cur_r.col1, cur_r.col2, ...);
exception
when others then
dbms_output.put_line(sqlerrm ||': '|| cur_r.col1 ||', '||cur_r.col2);
end;
end loop;
end;
内部BEGIN-END
块用于确保PL / SQL代码不会在第一个错误时退出,但会全部显示。然后查看这些值并找出使查询无效的原因。