ORA-00933: SQL 同时删除两个表时命令未正确结束
ORA-00933: SQL command not properly ended when deleting two tables at the same time
我正在尝试从两个相关的 table 中删除数据 - table users
中的主键和 table login
中的外键- 但我收到错误 PL/SQL: ORA-00933: SQL command not properly ended
.
创建tableusers
和主键:
/* 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);
创建tablelogin
以及主键和外键:
/* 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;
使用 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;
现在我想删除这个会话,但是我在这个过程中遇到错误 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;
我从 SQL 开发人员那里得到这张图片来显示错误(如果您看不到图片,DELETE FROM users, login ...
中 s,
上的红色波浪线下划线):
我做错了什么?
您不能在一个语句中从两个 table 中删除 - 没有 insert all
的删除等效项。 (除非您有级联删除的约束,或者手动执行此操作的触发器)。 The documentation 表明您的语法无效,因为没有指定多个 table.
的路径
您将需要两个删除语句,首先从子 table 中删除记录:
DELETE FROM login
WHERE login.id_user_login = p_id_user;
DELETE FROM users
WHERE users.id_user = p_id_user;
您可以将您的外键约束更改为delete cascade
:
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
... 这意味着您只需要明确地从 users
table 中删除;但这实际上可能不是您想要的,因为它删除了一个级别的验证 - 如果父密钥有子密钥,您可能希望防止其被意外删除。发布两次删除在这里并没有真正的伤害。
顺便说一句,您的第一个过程没有提交,这可能是您所期望的。在这一行中:
...
SELECT * FROM DUAL COMMIT;
... COMMIT
被解释为 DUAL
table 的别名,而不是单独的命令。 DUAL
后需要一个分号,COMMIT;
最好换行。但通常认为 而不是 在过程中提交,让顶级调用者决定是提交还是回滚以保持数据完整性更好。
我正在尝试从两个相关的 table 中删除数据 - table users
中的主键和 table login
中的外键- 但我收到错误 PL/SQL: ORA-00933: SQL command not properly ended
.
创建tableusers
和主键:
/* 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);
创建tablelogin
以及主键和外键:
/* 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;
使用 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;
现在我想删除这个会话,但是我在这个过程中遇到错误 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;
我从 SQL 开发人员那里得到这张图片来显示错误(如果您看不到图片,DELETE FROM users, login ...
中 s,
上的红色波浪线下划线):
我做错了什么?
您不能在一个语句中从两个 table 中删除 - 没有 insert all
的删除等效项。 (除非您有级联删除的约束,或者手动执行此操作的触发器)。 The documentation 表明您的语法无效,因为没有指定多个 table.
您将需要两个删除语句,首先从子 table 中删除记录:
DELETE FROM login
WHERE login.id_user_login = p_id_user;
DELETE FROM users
WHERE users.id_user = p_id_user;
您可以将您的外键约束更改为delete cascade
:
alter table login add constraint login_fk_user foreign key (id_user_login)
references users(id_user) on delete cascade;
... 这意味着您只需要明确地从 users
table 中删除;但这实际上可能不是您想要的,因为它删除了一个级别的验证 - 如果父密钥有子密钥,您可能希望防止其被意外删除。发布两次删除在这里并没有真正的伤害。
顺便说一句,您的第一个过程没有提交,这可能是您所期望的。在这一行中:
...
SELECT * FROM DUAL COMMIT;
... COMMIT
被解释为 DUAL
table 的别名,而不是单独的命令。 DUAL
后需要一个分号,COMMIT;
最好换行。但通常认为 而不是 在过程中提交,让顶级调用者决定是提交还是回滚以保持数据完整性更好。