Ben*_*Ben 5 sql versioning oracle data-dictionary
在识别Oracle数据库软件版本中 Oracle声明您可以通过查询PRODUCT_COMPONENT_VERSION找到"平台特定版本号"(补丁集):
要确定当前安装的Oracle数据库的发行版并查看您正在使用的其他数据库组件的发行版级别,请查询数据字典视图PRODUCT_COMPONENT_VERSION.
据此我们使用的是11.2.0.3.0
SQL> select * from product_component_version;
PRODUCT                             VERSION         STATUS
----------------------------------- --------------- ---------------
NLSRTL                              11.2.0.3.0      Production
Oracle Database 11g                 11.2.0.3.0      64bit Production
PL/SQL                              11.2.0.3.0      Production
TNS for Linux:                      11.2.0.3.0      Production
V $ VERSION也是如此(PRODUCT_COMPONENT_VERSION是偶然的视图):
SQL> select * from v$version;
BANNER
---------------------------------------------------------
Oracle Database 11g Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
但是,根据DBA_REGISTRY_HISTORY,数据库似乎在11.2.0.3.5上1:
SQL> select action, namespace, version, id, comments from dba_registry_history;
ACTION          NAMESPACE VERSION            ID COMMENTS
--------------- --------- ---------- ---------- ------------------------------
VIEW INVALIDATE                         8289601 view invalidation
UPGRADE         SERVER    11.2.0.3.0            Upgraded from 11.2.0.1.0
APPLY           SERVER    11.2.0.3            0 Patchset 11.2.0.2.0
APPLY           SERVER    11.2.0.3            5 PSU 11.2.0.3.5
DBA_REGISTRY_HISTORY不一定有任何数据,因此我无法可靠地使用此视图.而且,Oracle似乎没有提供填充注释字段的标准化方法,我似乎还在做以下操作,然后祈祷它有效.
select max(regexp_replace(comments, '[^[:digit:].]')) 
         keep (dense_rank first order by action_time desc)
  from dba_registry_history
是否有一种更简单,更可靠的方法来查找当前版本,包括补丁集,以编程方式?
1.也可能:我完全误读了这个,人们已经忘记了他们修补了什么.
由于我无法保证 DBA_REGISTRY_HISTORY 会被填充,即使它似乎提供了正确的补丁集,因此我最终执行了以下操作,以便在没有任何内容的情况下从 V$VERSION 进行填充。
with drh as ( 
select max(regexp_replace(comments, '[^[:digit:].]')) 
            keep (dense_rank last order by action_time) as vers
  from dba_registry_history
       )
 , v$v as ( 
select regexp_substr(banner, '(\d+\.?){5}', 1) as vers
  from v$version 
 where lower(banner) like 'oracle%'
       )
select coalesce(drh.vers, v$v.vers) as patch_set
  from drh
 right outer join v$v
   on 1 = 1
这是有效的,因为两个查询只会返回一行,并且我已经在 10.2、11.2 和 12.1 上测试了它
然而,这是荒谬和丑陋的。无法保证它不会损坏,因为所有内容都是自由文本字段,并且 Oracle 似乎偶尔会更改在这些视图中显示数据的方式。此外,Oracle 在这些观点中甚至不一致。这是一个 12c 数据库,注意注释字段在升级时神奇地恢复了补丁集,以及版本和注释如何不匹配。
SQL> select action, version, id, comments from dba_registry_history;
ACTION          VERSION          ID COMMENTS
--------------- ---------- -------- ------------------------
APPLY           11.2.0.3          0 Patchset 11.2.0.2.0
APPLY           11.2.0.3          0 Patchset 11.2.0.2.0
APPLY           11.2.0.3          5 PSU 11.2.0.3.5
VIEW INVALIDATE             8289601 view invalidation
UPGRADE         12.1.0.1.0          Upgraded from 11.2.0.3.0
APPLY           12.1.0.1          0 Patchset 12.1.0.0.0
6 rows selected.
因此,如果这些数据以易于使用的方式公开,那就太好了。