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; 最好换行。但通常认为 而不是 在过程中提交,让顶级调用者决定是提交还是回滚以保持数据完整性更好。