【问题标题】:plsql procedure that will delete rows将删除行的plsql过程
【发布时间】:2019-11-14 12:28:37
【问题描述】:

我有一个表 USERS 与列 username,fname, lname, age

如果年龄小于 18,我需要创建一个从参数中删除用户名的过程。

我写了一些代码,但它不起作用:

create procedure delete_user(username in varchar2)
as    
begin
    if exists (delete from username  where age < 18);

    dmbs_output.put_line(username);
end;
exec detele_user('mrgreen');

【问题讨论】:

  • if exists (delete ...) 不是有效的 SQL。您正在寻找delete from...where username =。再试一次。

标签: sql oracle plsql procedure


【解决方案1】:

方法如下。

先测试用例:

SQL> create table users
  2    (username varchar2(10),
  3     age      number);

Table created.

SQL> insert into users
  2    select 'LF'  , 10 from dual union all
  3    select 'Marc', 20 from dual;

2 rows created.

一个程序:

SQL> create or replace procedure delete_user (p_username in varchar2)
  2  is
  3  begin
  4    delete from users u
  5      where u.username = p_username
  6        and u.age < 18;
  7
  8    dbms_output.put_line('User ' || p_username ||
  9      case when sql%rowcount = 0 then ' NOT ' end ||
 10      ' deleted');
 11  end;
 12  /

Procedure created.

几点说明:

  • 不要将参数命名为表格列; Oracle 不知道哪个是哪个。使用前缀,例如p_
  • 始终使用表别名
  • 查看使用 sql%rowcount 的示例,它可以帮助您了解受影响的行数

最后,测试:

SQL> set serveroutput on;
SQL> exec delete_user('LF');
User LF deleted

PL/SQL procedure successfully completed.

SQL> exec delete_user('Marc');
User Marc NOT  deleted

PL/SQL procedure successfully completed.

SQL>

与您的问题无关,但是 - 如果您发布实际编译的代码通常会有所帮助。

  • dmbs_ 无效
  • 如果您将过程命名为delete_user,则不要调用detele_user

【讨论】:

  • 我工作得很好,但我发现另一个问题,用户名可以是另一个表的外键,必须弄清楚如何从子表中删除它
  • 如果外键约束是使用on delete cascade 选项创建的,Oracle 会为您完成。否则,手动从子表中删除行,然后从父表中删除。
【解决方案2】:

那么你基本上有 3 个选项。
1、在users表中增加一列“用户已被删除”。设置此项但不实际删除用户。
2. 将子表上的 FK 修改为“ON DELETE CASCADE”。 (如果 DBA 允许 - 许多/大多数不会)。
3. 修改删除子行的程序:下面是一种可能。

create or replace procedure delete_user (p_username in varchar2)
is
begin
   delete from child_table c
    where c.username = p_username
      and exists (select null 
                    from users u 
                   where u.username = p_username
                     and u.age < 18
                  );

   delete  from users u
    where u.username = p_username
      and u.age < 18; 

  dbms_output.put_line('User ' || p_username ||
                       case when sql%rowcount = 0 then ' NOT ' end ||
                       ' deleted');
end  delete_user ;

【讨论】:

  • 效果比我想象的要好(删除级联),谢谢帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多