以另一个用户身份执行Oracle存储过程

时间:2010-03-04 03:21:22

标签: sql oracle plsql schema oracle11g

我主要是一个神谕新手,如果这是一个愚蠢的问题,请原谅我......

我有一个名为'CODE'的模式,其存储过程执行任意SQL(现在请忽略与之相关的潜在安全问题)。传入的SQL将选择数据;但是所有数据都驻留在模式A,B或C中 - 但SQL一次只能从一个模式中选择。

例如:类型A的用户创建一个字符串'SELECT * FROM A.USERTABLE' - 而类型B的用户创建一个字符串'SELECT * FROM B.USERTABLE'。

我要做的是允许用户不明确指定其架构。在前端.net应用程序中;我已经知道他们是A型,B型还是C型。我希望这三个人只需输入'SELECT * FROM USERTABLE'。

我遇到的问题是我不知道该怎么做。我的应用程序只能在'CODE'模式中执行proc - 所以我不能只复制代码并让用户A调用'A.ExecuteSQL'。

我尝试了一些事情;但迄今为止没有任何工作。我希望ExecuteSQL proc保留在CODE模式中;但是当'USERTABLE'传入时,我需要知道有时这意味着A.USERNAME,有时候是B.USERNAME。

有什么建议吗?

2 个答案:

答案 0 :(得分:10)

使用:

ALTER SESSION SET CURRENT_SCHEMA = schema

那是equivalent to SQL Server's EXECUTE AS syntax

答案 1 :(得分:7)

另一种选择是使用AUTHID CURRENT_USER编译指示。

如果在包,过程,函数或类型名称之后立即添加这两个关键字,它将使用执行用户的权限而不是CODE模式执行。这将覆盖默认行为,即AUTHID DEFINER(编译代码的模式/用户的权限)

CREATE FUNCTION examplefunc
    (pSqlStatement IN VARCHAR2)
RETURN INTEGER
  AUTHID CURRENT_USER
AS 
   lResult INTEGER;
BEGIN
    EXECUTE IMMEDIATE pSqlStatement INTO lResult;
    RETURN lResult;
END examplefunc;

请注意,对于包内部的函数和过程,pragma只能在包级别应用。您无法基于每个功能设置权限。

这应该导致函数,包等中的任何SQL以用户权限执行。

我用它来管理类似的'动态运行任何旧的SQL动作'例程 - 至少你会阻止'普通'用户使用你的存储过程删除表或安装CODE模式中的其他代码。

(它可能也值得 - 如果你还没有 - 添加一些验证来抛出某些关键字 - 即必须以SELECT开头,不得包含嵌入式pl / sql块 - 无论你怎么做都不会破坏现有的码)。