我主要是一个神谕新手,如果这是一个愚蠢的问题,请原谅我......
我有一个名为'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。
有什么建议吗?
答案 0 :(得分:10)
答案 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块 - 无论你怎么做都不会破坏现有的码)。