在Oracle中实现用户定义的db参数/属性

时间:2009-11-08 13:15:31

标签: oracle

好吧,问题标题可能并不是最好的,但我正在寻找一种很好的方法来为Oracle数据库应用程序实现一个可扩展的参数集,这些参数“与主机/实例保持一致”。通过“保持”,我的意思是我想排除只有一个名称/值对的Oracle表,如果我通过克隆生产实例创建一个测试/ QA实例,则必须修改它。 (例如,假设一个名为email_error_address的参数应该在生产中设置为prod_support@abc.com,在测试中设置为qa_support@abc.com。)

需要从数据库中运行的PL / SQL代码以及客户端代码访问这些参数。我开始通过重载plsql_cc_flags init参数(不是我引以为豪的解决方案)来做到这一点,但是维护和解析会变得很混乱。

[编辑] 理想情况下,实现将允许更改列表而不重新启动实例,类似于动态可修改的init参数。

4 个答案:

答案 0 :(得分:1)

您希望为每个环境设置一组单独的值。您希望这些值独立于数据,以便在从其他实例导入数据时不会覆盖它们。

解决方案是使用外部表(假设您使用9i或更高版本)。由于外部表将数据保存在OS文件中,因此它们独立于数据库。要应用更改的值,您只需要覆盖操作系统文件。

您需要做的就是确保每个环境的文件保持独立。如果Test,QA,Production等在他们自己的服务器上,这很容易。如果它们在同一台服务器上,那么您需要通过文件名或目录路径来区分它们;在任何一种情况下,您可能需要发出一些DDL以在数据库刷新时更正位置。

使用外部表的缺点是它们可能有点性能开销 - 它们实际上是用于批量加载。如果这可能是一个问题,您可以使用缓存,使用用户定义的命名空间或CONTEXT。使用DBMS_SESSION.SET_CONTEXT()使用ON LOGON触发器将值加载到内存中。通过对SYS_CONTEXT()的包装调用来检索值。因为命名空间在会话中,内存检索速度非常快。 RenéNyffenegger有一个使用CONTEXTcheck it out的简单示例。

虽然我一直在写这篇文章,但我发现你已经添加了动态更改内容的要求。正如我已经说过的,使用OS文件很容易,但使用缓存会使事情变得更加困难。解决方案是使用全球可访问的CONTEXT。有一个例程可以在启动时加载所有值,您也可以在刷新OS文件时调用它们。

答案 1 :(得分:0)

您可以使用可以根据oracle用户(启动Oracle数据库的帐户)或每台服务器设置的环境变量。可以使用DBMS_SYSTEM.GET_ENV过程读取环境变量。

答案 2 :(得分:0)

我倾向于使用system_parameters表。如果您关注它被覆盖,请将其置于自己的架构中并制作公共同义词。

答案 3 :(得分:0)

@APC的答案很聪明。

您可以通过在外部表之上添加实例化视图来解决性能开销。您将在克隆RMAN之后以及每次更新配置文件后刷新它。