oracle - 防止 Oracle 包在生产中执行
问题描述
我创建了一个 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 :(
是否有常见的习惯用法或已知的方法来防止包在特定环境中执行?(例如,不必在包的每个过程/函数中复制相同的代码,以检查它是否有权执行)。
谢谢
解决方案
通常有相反的要求:即,您有在 PROD 中运行的进程,而您不想在 DEV 中运行(或不以相同的方式运行)。例如,您可能有一个程序生成一个文件并将其通过 FTP 发送给贸易伙伴。从 PROD 克隆后,您不希望它意外地在 DEV 中运行。
我们将需求的实现构建到我们的代码中,而不是依赖于数据库级别的东西,比如在某些环境中删除对象(或在克隆后不断地在 DEV 实例中重新安装东西)和/或撤销安全性。通过将东西构建到我们的代码中,我们不仅可以灵活地防止某些东西在一个或另一个实例中运行,还可以让它运行但以不同的方式运行(例如,生成 FTP 文件,但将其发送到测试服务器而不是贸易伙伴)。
为此,我们有一条具有生产数据库名称的数据(我们为此使用称为“配置文件值”的应用程序功能,但您可以将其放在自定义表中)。
然后,在任何环境敏感的过程中:
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;
这很简单,但不幸的是确实需要编码。
推荐阅读
- angular - 你如何在 Angular 中读取当前 PWA 的版本哈希?
- jquery - 如何删除或更改按钮 .btn.btn-outline-secondary bootstrap-show-password 的属性“标题”?
- pyspark - PySpark中随机森林树的可视化?
- javascript - 将 URL 参数传递给另一个 URL 的最简单方法是什么?
- android - 如何根据在 kotlin 中使用的键对 json 响应进行排序
- github - 仅当以下情况为真时,如何触发 Github 操作?
- python - Python声明一个变量列表而不初始化它们
- python - opencv轮廓上的等距采样
- sql - 如何在postgresql中使用索引选择数组中的值?
- html - HTML 电子邮件无法从网络加载自定义字体