Oracle 同一PL/SQL函数返回两个不同的值

Oracle 同一PL/SQL函数返回两个不同的值,oracle,Oracle,我有一个I PL/SQL函数,用于检查角色是否对某个对象具有权限 CREATE OR REPLACE FUNCTION HasPrivilegeOnObject(rolename IN VARCHAR2, objectname IN VARCHAR2, objectowner IN VA

我有一个I PL/SQL函数,用于检查角色是否对某个对象具有权限

CREATE OR REPLACE FUNCTION HasPrivilegeOnObject(rolename      IN VARCHAR2,
                                                objectname    IN VARCHAR2,
                                                objectowner   IN VARCHAR2,
                                                privilegename IN VARCHAR2)
  RETURN NUMBER
AS
  output NUMBER;
  BEGIN
    SELECT count(*) INTO output
    FROM dba_tab_privs
    WHERE
      grantee = rolename AND
      owner = objectowner AND
      table_name = objectname AND
      privilege = privilegename;

    IF output > 0 THEN
      output := 1;
    END IF;

    RETURN output;
  END hasprivilegeonobject;
要检查它,我需要:

call dbms_output.put_line(HasPrivilegeOnObject('Role1','Table1','TableOwner','UPDATE'));
结果为:1

但当我运行与函数中相同的查询时:

    select count(*) from DBA_TAB_PRIVS where 
        GRANTEE = 'Role1' and
        OWNER = 'TableOwner' and
        TABLE_NAME = 'Table1' and
        Privilege = 'UPDATE';  
结果为0。

有人知道这有什么问题吗?

确保对象名使用大写,即使在将对象名作为参数传递时也是如此,除非您专门创建了带双引号的对象。如果在创建对象名时不使用双引号,则对象名在内部存储为大写

您没有初始化输出-函数的返回值。如果查询与任何行都不匹配,会发生什么情况?这意味着返回值可能是不确定的

除非特别使用双引号将Table1命名为Table1(创建Table1时),否则Table1将作为Table1存储在数据字典的内部。这意味着,如果使用“Table1”的ObjectName(表名)参数调用函数中的查询,则该查询可能不一定匹配任何行


这也不是必需的,但最好在函数中添加一个异常处理程序,以确保异常不会阻止返回值按预期进行完全设置。

在函数中,ObjectName“Table1”用于表\名称过滤器,但在实际查询中,它采用RoleName“Role1”,因此,我认为结果是不同的。在这两种情况下,参数都不同,这可能导致o/p不同。这实际上是将查询复制到Stackoverflow时的一个错误:)!我编辑了这个帖子。这就是更改帖子内容的问题;有可能(在本例中甚至有可能)两个示例中使用的值有所不同,但由于您更改了它们,我们无法发现它。我猜你可能是输入错误或是换了两个字段,但这只能是猜测而已。添加“where rownum 0…”代码。虽然我同意大写字母的问题,但这些值在发布的版本中已被替换,因此不清楚这是否真的是原因,尽管很可能是(请参阅我之前的注释*8-)。不初始化
输出
不是问题<代码>计数(*)必须向该变量返回一个值。如果查询以某种方式失败,那么函数将抛出异常-添加处理程序(“when others”!?)更有可能掩盖问题,而不是帮助识别问题,不是吗?嗨。。我重新检查了这篇文章,我仍然看到这篇文章的表1不是大写的;它可能已经更新,因为我现在检查;我注意到,如果PLSQL查询返回零行,ORACLE不会抛出异常;如果查询在语法上是有效的,并且引用了有效的对象,但与任何行都不匹配,则不会引发异常;我试图找出在没有匹配行的情况下,该代码将如何初始化。是的,但示例中显示了函数调用和简单查询的
'Table1'
(等);如果这是(仅仅)一个案例问题,那么双方都将无法获得资助。因此,要么实数查询使用大写名称,要么一个使用,一个不使用,但是OP没有显示所使用的实际实数。总的来说,你是对的,但我认为我们没有足够的信息来说明这是问题所在——尽管如果使用了不一致的值,这很可能是问题所在。如果没有匹配的行,
count(*)
仍然将
输出设置为
0
-它不能设置
输出;但为什么他的post语句SQL SELECT(非PLSQL查询)返回的计数为零?零不是意味着数据字典中没有匹配项吗?这似乎与内部命名为TABLE1而不是TABLE1的表一致。有人知道他的哪个查询返回表1(而不是表1)的非零计数吗?也许我还没有看到他的最新更新。因为
Table1
不是真正的表名;这些值已针对问题进行了更改。如果值相同,则查询应返回相同的计数。因此它们不是-但是因为它们已经被问题改变了(我猜是为了隐藏真实的模式),所以OP在真实的、未改变的查询中的错误并不明显。拼写错误、大小写错误、值与正确的列不一致——我们只能猜测。