【问题标题】:PLS-00320: the declaration of the type of this expression is incomplete or malformed - ORACLE PRIVILEGES ISSUEPLS-00320:此表达式类型的声明不完整或格式错误 - ORACLE PRIVILEGES ISSUE
【发布时间】:2018-09-21 18:03:46
【问题描述】:

我正在尝试实现 Oracle 数据库安全指南中公开的数据库安全性,我的场景是这样的:

  • 用户OWNER创建表TABLE_A;
  • 用户 OWNER 创建一个包 PKG_A,在 TABLE_A 上包装业务逻辑,如下所示:

    package body PKG_A AS
    procedure doSomeManagerStuff (pRow TABLE_A%rowtype) as 
    begin
    ... 
    end;
    
    procedure doSomeDataEntryStuff (pRow TABLE_A%rowtype) as 
    begin
    ...
    end;
    
    procedure doSomeVisitorStuff (pRow TABLE_A%rowtype) as 
    begin
    ...
    end;
    
    end PKG_A;
    

-user OWNER 创建 n 个过程,每个过程调用一个包的一个公共过程:

procedure ManagerStuff (pRow TABLE_A%rowtype) as
begin
 pkg_a.doSomeManagerStuff (pRow);
end;

procedure DataEntryStuff (pRow TABLE_A%rowtype) as
begin
  pkg_a.doSomeDataEntryStuff (pRow);
end;

procedure VisitorStuff(pRow TABLE_A%rowtype) as
begin
  pkg_a.doSomeVisitorStuff (pRow);
end;
  • 用户 OWNER 创建角色 ROLE_MANAGER、ROLE_DATAENTRY、ROLE_VISITOR
  • 用户所有者授予执行相应角色的过程
  • 此时,为了测试安全性,我创建了具有不同角色的不同用户并尝试了这样的脚本:

    /** CONNECTED AS USERMANAGER **/
    declare
      lRow OWNER.TABLE_A%rowtype; /* --- Which privilege I need to grant? --- */
    begin
      lRow.field1 := value;
      ...
      OWNER.ManagerStuff(lRow);
    end;
    

我想处理传递代表整个表格行的单个参数的过程。这样,我的意愿是每次更改表结构或应用在包中的业务逻辑时,不必修改每个程序。

我们将不胜感激任何建议或不同的方法。

【问题讨论】:

  • 对我来说似乎还可以。您可以创建同义词,这样您就不必每次都指定所有者名称;此外,“不同的用户”甚至不必知道所有者,不是吗?
  • @Littlefoot :你是对的......但是:“[...]当您授予同义词的对象权限时,您实际上是在授予基础对象的权限 [...]”同义词 (docs.oracle.com/cd/B28359_01/server.111/b28310/…) 这不是我希望用户能够做的事情。
  • 我并不是说你应该授予同义词的权限——它们是在表和过程上授予的。但是您可以在“其他用户的架构”中创建同义词,甚至可以创建公共同义词(虽然这是一个更糟糕的主意,但可能取决于特定情况)。
  • @Littlefoot :我同意你的说法,但我的问题是要传递给过程的参数,而不是调用过程的方式(如果不够清楚,抱歉)。
  • 对于USERMANAGER 来解析OWNER.TABLE_A%rowtype,它需要SELECTOWNER.TABLE_A 的特权,直接或通过角色。请注意,角色权限对存储的 PL/SQL 无效,但可以在您的示例中的匿名块中工作。

标签: oracle privileges


【解决方案1】:

我使用答案来更好地公开解决方案。

William Robertson 的评论是正确的,但我阅读了here 关于 SELECT 权限的信息。所以我不希望用户可以直接访问我的表,并且拥有 READ 权限,我可以通过这种方式引用 rowtype

declare
 lRow owner.table_a%rowtype;
begin
 null;
end;

我读过this,虽然帖子很旧,但我试试这个:

  • 我创建了一个没有body的包:

    create or replace PACKAGE PKG_TYPES AS 
    
      subtype table_A_rt is table_A%rowtype;
      subtype table_B_rt is table_B%rowtype;
      subtype table_C_rt is table_C%rowtype;
      ...
    
    END PKG_TYPES
    
  • grant EXECUTE on pkg_types to ROLE_MANAGER

  • 现在可以引用 rowtype 了:

    declare
     lRow asadmin.pkg_types.account_rt;
    begin
     null;
    end;
    

我仍在努力,但它似乎满足了我的需求。 任何优点和缺点都表示赞赏。

【讨论】:

    猜你喜欢
    • 2021-12-25
    • 1970-01-01
    • 2021-04-26
    • 2021-03-29
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多