我创建了一个Oracle PL/SQL包,希望防止它在生产环境或特定数据库上执行,这可能很危险。事实上,事实证明我有管理权限,并且可能无意中在生产环境中编译开发包。
我试着用类似于以下内容的东西检查包正文中的上下文:
create or replace package body my_test_package is
context varchar2(64);
function get_context return varchar2 is
begin
-- return context: DEV or PROD
...
end;
-- list of other functions & procedures ....
begin
if context = 'PROD' then
dbms_standard.raise_application_error(-20001, 'production context, prevent execution of this package');
end if;
end;但是,我知道这是一个糟糕的解决方案,因为初始化时间只发生一次(),正如Oracle文档所述。
包的初始化部分起次要作用,因为与子程序不同,包不能调用或传递参数。因此,在第一次引用包时,包的初始化部分只运行一次。
因此,这意味着在第一个过程之后的所有后续过程调用都将被执行,即使在生产环境中也是如此。例如:
-- production environment
begin
my_test_package.dangerous_procedure();
exception when others then
dbms_output.put_line('bypass context exception');
end;
my_test_package.dangerous_procedure(); ---> EXECUTED IN PROD :(是否有常见的成语或已知的方法来防止在特定环境中执行包?(例如,不必在包的每个过程/功能中复制相同的代码,就可以检查它是否有权执行)。
谢谢
发布于 2019-12-09 16:31:30
在相反的方向上有这样的需求是很常见的:也就是说,您有一些进程运行在PROD中,而您不想在DEV中运行(或者不是以相同的方式运行)。例如,您可能有一个生成文件并将其发送给贸易伙伴的程序。你不会想让它在DEV运行后偶然从PROD克隆。
我们将需求的实现构建到代码中,而不是依赖于数据库级的东西,比如在某些环境中删除对象(或者在克隆之后不断地在DEV实例中重新安装东西)和/或撤销安全性。通过将内容构建到代码中,我们不仅可以灵活地防止某物在一个或另一个实例中运行,而且可以让它运行但以不同的方式运行(例如,生成FTP文件,但将其发送到测试服务器而不是贸易伙伴)。
为此,我们有一段具有生产数据库名称的数据(我们为此使用了一个名为"profile values“的应用程序特性,但您可以将其放在自定义表中)。
然后,在任何对环境敏感的过程中:
BEGIN
l_db_name := xxcust_common_utils_pkg.get_production_dbname; -- you write this function based on where you put the production database name...
IF sys_context('USERENV','DB_NAME') = l_db_name THEN
... act like you want to in production
ELSE
... act like you want to in non-production
END IF;
END;这很简单,但不幸的是,它确实需要编码。
https://stackoverflow.com/questions/59252447
复制相似问题