2010-03-04 117 views
8

我主要是一个oracle新手,所以请原谅我,如果这是一个愚蠢的问题...执行Oracle存储过程作为另一个用户

我有一个名为“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过程保持在CODE模式中;但是当'USERTABLE'通过时,我需要知道有时这意味着A.USERNAME,有时候B.USERNAME。

有什么建议吗?

回答

10

用途:

ALTER SESSION SET CURRENT_SCHEMA = schema 

这是equivalent to SQL Server's EXECUTE AS syntax

+0

这是如何工作的?第一个应用程序执行这个'ALTER'语句或者在'CODE'过程中执行这个语句? – Guru 2010-03-04 03:41:33

+1

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:588045400346317188有更多信息。它看起来像你可以用你的存储过程中的动态sql(立即执行)来完成它。 – 2010-03-04 04:24:22

+0

@Guru:请参阅Rob P的AskTom链接 – 2010-03-04 04:49:01

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; 

注意,对于函数和过程内幕包时,编译指示只能应用于在包级别。您不能在每个功能的基础上设置权限。

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

我用它来管理类似的'动态运行任何旧的SQL位' - 至少你会阻止'普通'用户无法使用存储过程删除表或在CODE模式中安装其他代码。如果你还没有 - 添加一些验证来抛出某些关键字 - 也就是说,必须以SELECT开头,不能包含嵌入的pl/sql块 - 不管你可以在不破坏的情况下,现有的代码)。

相关问题