代码之家  ›  专栏  ›  技术社区  ›  Thelnternet

APEX 4.2验证,至少一行必须有一个值

  •  1
  • Thelnternet  · 技术社区  · 7 年前

    我有一个定义具有管理权限的用户的表。该表有一列标记为ADMINISTRATOR。设置apex表格形式,使列显示为复选框。当存在检查时,值为1。当检查为空时,该值为null。

    我的问题是,任何访问此页面的管理员都可以向任何人添加或吊销管理员权限。这意味着,如果某个管理员意外或故意撤销包括他自己在内的所有其他管理员的权限,则任何人都无法在前端访问该工具。

    我想建立一个验证,要求系统至少有一个管理员,如果有人试图更新管理员列中没有1的表,则会引发错误。

    我一直在努力确定什么样的验证最有效。

    我最近的尝试是:

    类型: Function returning a boolean

    表达式:

    declare
       admincount   number(8);
    begin
    
    select count(administrator) into admincount from supervisor;
    
    if admincount < 1 then
       return false;
    else
       return true;
    end if;
    end;
    

    当我尝试在Oracle SQL Developer上运行此脚本时,我得到:

    Error report -
    ORA-06550: line 8, column 4:
    PLS-00372: In a procedure, RETURN statement cannot contain an expression
    ORA-06550: line 8, column 4:
    PL/SQL: Statement ignored
    ORA-06550: line 10, column 4:
    PLS-00372: In a procedure, RETURN statement cannot contain an expression
    ORA-06550: line 10, column 4:
    PL/SQL: Statement ignored
    06550. 00000 -  "line %s, column %s:\n%s"
    *Cause:    Usually a PL/SQL compilation error.
    *Action:
    

    此代码有什么问题?我是否将此表达式应用于错误的位置?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Kris Rice    7 年前

    apex中发生的情况是,您的块实际上已转换为函数。

    declare
       admincount   number(8);
    begin
    
    select count(administrator) into admincount from supervisor;
    
    if admincount < 1 then
       return false;
    else
       return true;
    end if;
    end;
    

    内部更改为具有返回值的此函数。然后引擎调用这个。隔离的匿名块不能有return语句,否则您将看到错误。

    declare
     ret boolean;
     function x return boolean is
        begin
        declare
           admincount   number(8);
        begin
    
          select count(administrator) into admincount from supervisor;
    
          if admincount < 1 then
             return false;
          else
             return true;
          end if;
        end;
      end;
    
      begin
         ret := x;
      end;
    

    最好的方法是将逻辑转换为实际函数

    create or replace function is_admin return boolean
    as 
       admincount   number(8);
    begin
    
    select count(administrator) into admincount from supervisor;
    
    if admincount < 1 then
       return false;
    else
       return true;
    end if;
    end;
    

    然后,您可以在sqldev/sqlcl或任何工具中测试此函数。

    然后在APEX中使用的结果表达式为

    return is_admin;
    
        2
  •  1
  •   Littlefoot    7 年前

    这在SQL Developer中不起作用;必须将布尔值返回到 某物 (另一个PL/SQL过程),然后决定要执行的操作。下面是一个示例:

    SQL> select * From ts65_supervisor order by id;
    
            ID ADMINISTRATOR
    ---------- -------------
             1             1
             2             1
             3
             4
             5             1
    
    SQL> create or replace function f_super return boolean as
      2    admincount number;
      3  begin
      4    select count(administrator) into admincount from ts65_supervisor;
      5
      6    return admincount > 1;
      7  end;
      8  /
    
    Function created.
    

    可以吗?(3名管理员-应为):

    SQL> begin
      2    if f_super then
      3       dbms_output.put_line('OK, more than 1 admin');
      4    else
      5       dbms_output.put_line('The last one');
      6    end if;
      7  end;
      8  /
    OK, more than 1 admin
    
    PL/SQL procedure successfully completed.
    

    更新后?

    SQL> update ts65_supervisor set administrator = null where id < 5;
    
    4 rows updated.
    
    SQL> begin
      2    if f_super then
      3       dbms_output.put_line('OK, more than 1 admin');
      4    else
      5       dbms_output.put_line('The last one');
      6    end if;
      7  end;
      8  /
    The last one
    
    PL/SQL procedure successfully completed.
    
    SQL>
    

    我建议您不要在SQL Developer中进行测试,而是直接在Apex中进行测试-它会将您的代码包装到自己的开始-结束块中,该函数可能工作得很好(请注意您的代码和我的代码之间的差异-您实际上不需要IF-THEN-ELSE-一个简单的返回条件就足以让Oracle知道返回哪个是真/假)。