【问题标题】:ORA-02291: integrity constraint () violated - parent key not foundORA-02291: 违反完整性约束 () - 未找到父键
【发布时间】:2015-07-29 05:21:50
【问题描述】:

我正在尝试为admin 和user 创建会话,这两个表都与具有相同外键的登录表相关联-但是当我为admin 创建会话时,我收到错误PL/SQL: ORA-02291: integrity constraint (login_fk_user) violated - parent key not found,在我在这个link 中的另一个问题,我没有以最好的方式解释,但是得到了一些关于使用(派对角色关系模型)的想法,并且他下面的这段代码与已经解决的问题link 更相关

创建表admin和主键

/* table admin*/
create table admin (id_admin number(10) not null, 
                    admin_name varchar(30) not null);
/* primary key */
alter table admin add constraint admin_pk primary key (id_admin);

创建表users和主键

/* table user*/
create table users (id_user number(10) not null, 
                    user_name varchar(30) not null);
/* primary key */
alter table users add constraint user_pk primary key (id_user);

创建表login和主键和外键

/* table login*/
create table login(id_login number(10) not null, 
                   id_admin_user_login number(10) not null, 
                   email_login varchar(20) not null, 
                   password_login varchar(10) not null);
/* primary key */
alter table login add constraint login_pk primary key (id_login);

/* foreign key reference to admin*/
alter table login add constraint login_fk_admin foreign key (id_admin_user_login) 
reference admin(id_admin);

 /* foreign key reference to user*/
alter table login add constraint login_fk_user foreign key (id_admin_user_login) 
reference users(id_user);

使用表 admin/login 为管理员创建会话的过程:

PROCEDURE create_admin_session( p_name   IN VARCHAR2,
                                p_email  IN VARCHAR2,
                                p_pass   IN VARCHAR2,
                                p_error  OUT NUMBER,
                                p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
INSERT ALL
INTO admin (id_admin, admin_name) VALUES(seq_admin.NEXTVAL, p_name)

INTO login(id_login, id_admin_user_login, email_login, pass_login)
VALUES(seq_login.NEXTVAL, seq_admin.CURRVAL, p_email, p_pass)

SELECT * FROM DUAL;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error     := 1;
p_msg_error := 'Error!'||SQLERRM;
END create_admin_session;

为具有表users/login的用户创建会话的过程:

PROCEDURE create_user_session( p_name   IN VARCHAR2,
                               p_email  IN VARCHAR2,
                               p_pass   IN VARCHAR2,
                               p_error  OUT NUMBER,
                               p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
INSERT ALL
INTO users (id_user, user_name) VALUES(seq_user.NEXTVAL, p_name)

INTO login(id_login, id_admin_user_login, email_login, pass_login)
VALUES(seq_login.NEXTVAL, seq_user.CURRVAL, p_email, p_pass)

SELECT * FROM DUAL;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error     := 1;
p_msg_error := 'Error!'||SQLERRM;
END create_user_session;

当我创建管理会话时,我收到了一个错误ORA-02291: integrity constraint (login_fk_user) violated - parent key not found

我做错了什么?

【问题讨论】:

  • 你的 FK 在这里没有意义。 id_admin_user_login 必须同时出现在 admin 和 user 表中,插入才能工作。我不明白你为什么有这样的用户和管理员表,看起来不太好管理。
  • 按我的逻辑我理解,但显然我错了
  • 那么肯定是每个用户和管理员有两个不同的外键,进入管理员,外键用户为空,如果相反是管理员的外键为空,对吧?
  • 在这种情况下我需要做id_admin_login number(10) null和id_user_login number(10) null ,
  • @Mat,按照你的推理,我想我已经做到了,一切都完美无缺,谢谢

标签: oracle plsql sql-insert


【解决方案1】:

在表登录中,我添加了两个id not null,一个用于用户id_user_login number(10) null,第二个用于管理员id_admin_login number(10) null

/* table login*/
create table login(id_login number(10) not null, 
                   id_admin_login number(10) null, 
                   id_user_login number(10) null, 
                   email_login varchar(20) not null, 
                   password_login varchar(10) not null);
/* primary key */
alter table login add constraint login_pk primary key (id_login);

/* foreign key reference to admin*/
alter table login add constraint login_fk_admin foreign key (id_admin_login) 
reference admin(id_admin) ON DELETE CASCADE;

 /* foreign key reference to user*/
alter table login add constraint login_fk_user foreign key (id_user_login) 
reference users(id_user) ON DELETE CASCADE;

使用表 admin/login 为管理员创建会话的过程:

PROCEDURE create_admin_session( p_name   IN VARCHAR2,
                                p_email  IN VARCHAR2,
                                p_pass   IN VARCHAR2,
                                p_error  OUT NUMBER,
                                p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
INSERT ALL
INTO admin (id_admin, admin_name) VALUES(seq_admin.NEXTVAL, p_name)

INTO login(id_login, id_admin_login, id_user_login, email_login, pass_login)
VALUES(seq_login.NEXTVAL, seq_admin.CURRVAL, NULL, p_email, p_pass)

SELECT * FROM DUAL;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error     := 1;
p_msg_error := 'Error!'||SQLERRM;
END create_admin_session;

为具有表users/login的用户创建会话的过程:

PROCEDURE create_user_session( p_name   IN VARCHAR2,
                               p_email  IN VARCHAR2,
                               p_pass   IN VARCHAR2,
                               p_error  OUT NUMBER,
                               p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
INSERT ALL
INTO users (id_user, user_name) VALUES(seq_user.NEXTVAL, p_name)

INTO login(id_login, id_admin_login, id_user_login, email_login, pass_login)
VALUES(seq_login.NEXTVAL, NULL, seq_user.CURRVAL, p_email, p_pass)

SELECT * FROM DUAL;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error     := 1;
p_msg_error := 'Error!'||SQLERRM;
END create_user_session;

有了这个决议,一切都完美无缺,如果我需要drop user/login,我会按照我的意愿工作

【讨论】:

  • 有时,良好的定位是必要的,这样我们才能获得逻辑感并思考解决问题或疑问的最佳方法,感谢@Mat您的定位
猜你喜欢
  • 2016-03-12
  • 2020-07-19
  • 2018-04-18
  • 2014-06-12
  • 2018-05-23
  • 2018-11-13
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
相关资源
最近更新 更多