【问题标题】:PL/SQL - Can't find my local variablePL/SQL - 找不到我的局部变量
【发布时间】:2018-04-03 12:28:55
【问题描述】:

我现在很困惑;我正在编写一个脚本来查找用户继承的所有角色。这是一项正在进行中的工作,由于我对 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;

此代码导致“找不到表或视图”错误,因为在第二行 (Select Count(*)...) 中找不到“toadd”,尽管它可以在上面的语句中找到 (Select GRANTED_ROLE...) 这怎么可能?

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

【问题讨论】:

  • 第二个问题请参考asktom.oracle.com/pls/asktom/…
  • 真的两个问题应该是两个帖子,但由于第一个问题回答得如此之快,我为第二个问题提供了奖励解决方案;)
  • 顺便说一句,您不需要BEGIN DECLAREEND 关键字之一。此外,一个集合有一个count 方法,所以你不需要 SQL 来找出它有多少元素。

标签: sql oracle plsql oracle11g


【解决方案1】:

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 语法。

【讨论】:

  • 像往常一样,来自 APC 的好建议。关于 BULK COLLECT 的一个小附录:选择批量收集到公式中对于相对较小的数据集来说非常好。但是,如果您将它与大量行一起使用,您可能最终会消耗过多的 PGA 内存。所以最好使用显式游标,然后使用 fetch-bulk collect 和 LIMIT 子句进行简单循环。这是一个带有示例的 LiveSQL 脚本:livesql.oracle.com/apex/livesql/file/…
  • @stevenfeuerstein - 如果他们授予角色的层次结构大到足以突破会话内存限制,我真的会担心 OP 的安全模型 ;-) 但在更广泛的使用中,你当然是对的。
  • 分层语法?哦,我的上帝,非常感谢你告诉我 :D 我真的以为我实际上必须正确学习 Oracle ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 2020-01-19
  • 2011-12-18
  • 2015-07-08
  • 2011-10-23
  • 2012-04-02
相关资源
最近更新 更多