PL / SQL - 找不到我的局部变量

时间:2018-04-03 12:28:56

标签: sql oracle plsql oracle11g

我现在很困惑;我正在编写一个脚本来查找用户正在进行的所有角色。这是一项正在进行的工作,由于我对PLSQL缺乏了解,如果你知道我的意思,那么进展并不是很多。

-- Declaration of Table Type
create or replace TYPE TEST 
AS TABLE OF VARCHAR(30);

-- Function here
create or replace FUNCTION FINDPARENTS 
(
  ROLENAME IN VARCHAR2 
) 
    RETURN TEST 
    IS
    tt_t TEST;

BEGIN
    DECLARE
        results test;
        toadd test := TEST(ROLENAME);
        counter number;
        elements number:=1;
    BEGIN
        SELECT GRANTED_ROLE 
        BULK COLLECT INTO toadd 
        FROM DBA_ROLE_PRIVS 
        WHERE GRANTEE = rolename; 

        SELECT COUNT(*) 
        INTO ELEMENTS 
        FROM toadd; -- Error here.
    --(for i in 0 .. ELEMENTS) SELECT FINDPARENTS(ROLE_NAME) FROM DUAL UNION RESULT ... or something.
    END;
END;

此代码导致“表或视图未找到”错误,因为在第二行中无法找到“toadd”(选择计数(*)...),尽管可以在上面的语句中找到(选择GRANTED_ROLE ......)这怎么可能?

此外,实现递归的最佳方法是什么?我的函数返回一个VARCHAR表,如何让它“解析”每个role_names,直到角色不再有父角色为止?

1 个答案:

答案 0 :(得分:5)

toadd是一个变量。我们不能在FROM子句中使用那些,只能使用表。但是,因为它被声明为嵌套表类型,我们可以将它转换为具有table()函数的表:

 SELECT COUNT(*) 
    INTO ELEMENTS 
    FROM table(toadd); 

为了回答问题的其他部分,Oracle有一些整洁的层次结构语法。 Find out more

因此,您可以获得所有直接或间接授予的角色的列表,如下所示:

select granted_role
bulk collect into tt_t
from dba_role_privs 
connect by granted_role = prior grantee
start with granted_role = 'ROOT'
/

填充集合时使用BULK COLLECT语法。