Ren*_*uza 1 oracle plsql sql-delete
我试图删除两个相关表中的数据 - 表中的主键和表中的users外键login- 但我收到错误PL/SQL: ORA-00933: SQL command not properly ended.
创建表users和主键:
/* table user*/
create table users (id_user number(10) not null,
name_user varchar(30) not null);
/* primary key */
alter table users add constraint user_pk primary key (id_user);
Run Code Online (Sandbox Code Playgroud)
创建表login和主键以及外键:
/* table login*/
create table login (id_login number(10) not null,
id_user_login number(10) not null,
email_login varchar(20) not null,
password_login varchar(20) not null);
/* primary key */
alter table login add constraint login_pk primary key (id_login);
/* foreign key reference to user*/
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
Run Code Online (Sandbox Code Playgroud)
使用table 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, name_user) VALUES(seq_user.NEXTVAL,p_name)
INTO login(id_login, id_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;
Run Code Online (Sandbox Code Playgroud)
现在我想删除此会话,但我PL/SQL: ORA-00933: SQL command not properly ended从此过程中得到错误:
PROCEDURE delete_user_session(
p_id_user IN NUMBER,
p_error OUT NUMBER,
p_msg_error OUT VARCHAR2)
IS
BEGIN
p_error := 0;
DELETE FROM users, login USING users
INNER JOIN login WHERE users.id_user = p_id_user
AND login.id_user_login = p_id_user;
COMMIT;
EXCEPTION
WHEN OTHERS THEN
p_error := 1;
p_msg_error := 'Error!'||SQLERRM;
END delete_user_session;
Run Code Online (Sandbox Code Playgroud)
我有来自SQL开发人员的这个图像来显示错误(如果你看不到图像s,,DELETE FROM users, login ...则在in中出现红色波浪线下划线):

我究竟做错了什么?
您不能在一个语句中从两个表中删除 - 没有删除等效的insert all.(除非您具有级联删除的约束或手动执行此操作的触发器).文档显示您的语法无效,因为没有指定多个表的路径.
您需要有两个delete语句,首先从子表中删除记录:
DELETE FROM login
WHERE login.id_user_login = p_id_user;
DELETE FROM users
WHERE users.id_user = p_id_user;
Run Code Online (Sandbox Code Playgroud)
您可以将外键约束更改为delete cascade:
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
Run Code Online (Sandbox Code Playgroud)
...这意味着你只需要从users表中明确删除; 但这可能实际上并不是你想要的,因为它删除了一个级别的验证 - 你可能想要防止父键在有子级时被意外删除.发出两次删除并不会在这里造成伤害.
顺便提一下,您的第一个程序不是提交,这可能是您所期望的.在这一行:
...
SELECT * FROM DUAL COMMIT;
Run Code Online (Sandbox Code Playgroud)
... COMMIT被解释为DUAL表的别名,而不是单独的命令.之后你需要一个分号DUAL,最好是一个新的代号COMMIT;.但通常认为最好不要在过程中提交,并让顶级调用者决定是提交还是回滚以保持数据完整性.