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

APEX 4.2 validation, at least one row must have a value

我有一个 table 定义了具有管理权限的用户。 table 有一个标签为 ADMINISTRATOR 的列。顶点表格形式已设置,因此该列显示为复选框。当有支票时,值为1。当支票为空时,值为空。

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

我想建立一个验证,要求系统至少有一个管理员,并在有人试图更新 table 时在 ADMINISTRATOR 列中没有 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:

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

这在 SQL 开发人员中不起作用;您必须将 return BOOLEAN 转换为 something(另一个 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 中进行测试 - 它会将您的代码包装到它自己的 BEGIN - END 块中,并且该功能可能会正常工作(注意你的代码和我的代码之间的区别——你实际上不需要 IF-THEN-ELSE——一个带有条件的简单 RETURN 就足以让 Oracle 知道 TRUE/FALSE 到 return).

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 值的此函数。然后引擎调用它。孤立的匿名块不能有 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;