我有 2 个查询。第一个查询在 11g 上运行: 从 dba_directories 中选择所有者、目录名称、目录路径;
第二个仅在 12c 和 19c oracle 版本上运行: 从 cdb_directories 中选择所有者、目录名称、目录路径;
目标是将这 2 个 sql 组合成一个查询,以便它在任何版本的数据库上无缝运行,没有任何错误。 请注意,组合查询将作为指标在 OEM 中运行。
我尝试了一些变体,但没有成功。
with version_check as ( select case when substr(version,1,2)= '11' then '11' else 'OTHER' end as db_version from v$instance ) select d.db_unique_name||':'||dd.owner||':'||dd.directory_name DB_OWNER_DIRECTORY,dd.owner, dd.directory_name, dd.DIRECTORY_PATH from dba_directories dd, v$database d where (select db_version from version_check)= '11' union all select d.db_unique_name||':'||cd.owner||':'||cd.directory_name DB_OWNER_DIRECTORY, cd.owner,cd.directory_name,cd.directory_path FROM cdb_directories cd, v$database d WHERE cd.origin_con_id NOT IN (0, 1) AND (REGEXP_LIKE (cd.directory_path,sys_context('USERENV', 'ORACLE_HOME')) OR REGEXP_LIKE (cd.directory_path,'/tmp') OR REGEXP_LIKE (cd.directory_path,'/usr/tmp')) and (select db_version from version_check)<> '11';
上面给出了ORA-00942:表或视图不存在
你将无法做到这一点 - SQL 语句中的对象名称必须在解析时可解析,并且 11g 中没有
cbd*
视图,因此你的 SQL 将始终无法解析。
您将必须使用特定于版本的 SQL,该 SQL 在运行时由 SQL 以外的其他内容确定。这可以是使用动态 SQL (
EXECUTE IMMEDIATE
) 来防止解析不适当的 SQL 的 PL/SQL,也可以是数据库之外的任何编程语言。
我建议后者;多年来,我编写并管理了一个广泛的监控系统,涵盖从 8i 到 19c 的每个版本。我为每个版本化的 SQL 语句或 PL/SQL 块保留版本化的脚本片段(例如,这里是 8i 版本,这里是 10.2.0.1 到 10.2.0.4 等),然后在运行时将每个脚本片段的适当版本拼凑在一起是时候创建一个可以针对该特定版本运行的完整版本化脚本了。