2

是的,我知道DatabaseMetadata.getIndexInfo但它似乎没有做我想要的。

我有两个用户/模式,我们称他们AB.

有一个表A被调用TAB。用户B在 上创建了一个索引A.TAB,我们称之为索引IND

想要TAB的信息是:架构中的表上有哪些索引A(也就是 owner A)。我不关心索引的所有者,只关心它们在那个特定的表上。

通过实验,getIndexInfo我发现了以下几点:

  • catalogOracle JDBC 驱动程序似乎完全忽略了第一个参数。
  • 第二个参数schema限制返回哪些表统计信息 以及 索引的所有者
  • uniqueapproximate(大致)做他们应该做的(除了给予approximate=false将实际执行更新统计语句)。

跟踪 JDBC 驱动程序在其上执行的 SQL 后getIndexInfo(null, "A", "TAB", false, true),我得到了这个:

select null as table_cat,
       owner as table_schem,
       table_name,
       0 as NON_UNIQUE,
       null as index_qualifier,
       null as index_name, 0 as type,
       0 as ordinal_position, null as column_name,
       null as asc_or_desc,
       num_rows as cardinality,
       blocks as pages,
       null as filter_condition
from all_tables
where table_name = 'TAB'
  and owner = 'A'
union
select null as table_cat,
       i.owner as table_schem,
       i.table_name,
       decode (i.uniqueness, 'UNIQUE', 0, 1),
       null as index_qualifier,
       i.index_name,
       1 as type,
       c.column_position as ordinal_position,
       c.column_name,
       null as asc_or_desc,
       i.distinct_keys as cardinality,
       i.leaf_blocks as pages,
       null as filter_condition
from all_indexes i, all_ind_columns c
where i.table_name = 'TAB'
  and i.owner = 'A'
  and i.index_name = c.index_name
  and i.table_owner = c.table_owner
  and i.table_name = c.table_name
  and i.owner = c.index_owner
order by non_unique, type, index_name, ordinal_position

如您所见,两者都 table_name i.owner限制为TAB. 这意味着此查询将返回与表相同的用户拥有的索引信息。

我可以想到三种可能的解决方法:

  1. 始终在相同的模式中创建索引和表(即让它们具有相同的所有者)。不幸的是,这并不总是一种选择。
  2. 查询schema设置为null。一旦两个模式包含相同的表名,这将变得很难看(因为没有办法找出给定模式在哪个表(即哪个表所有者)上)。
  3. 直接执行该 SQL(使用executeQuery())。我宁愿不要跌到这个水平,除非它是绝对不可避免的。

这些变通方法对我来说都不是特别令人满意,但如果没有其他方法可行,我可能不得不退回到直接 SQL 执行。

数据库和 JDBC 驱动程序都位于 11.2.0.2.0。

所以基本上我的问题是:

  1. 这是 JDBC 驱动程序中的错误,还是背后有一些我不知道的逻辑?
  2. 是否有一种简单且可移植的方式让 Oracle 为我提供所需的信息?
4

2 回答 2

1

始终在相同的模式中创建索引和表(即让它们具有相同的所有者)。不幸的是,这并不总是一种选择。

那将是我的首选方式。

将架构设置为 null 的查询。一旦两个模式包含相同的表名,这将变得很难看(因为无法找出给定模式在哪个表(即哪个表所有者)上)

当然,您可以发现这一点,因为 getIndexInfo() 返回的结果集确实包含每个表的正确模式。但是您无法找出索引在哪个模式中。

直接执行那个 SQL

我实际上会使用该查询的修改版本,该版本还返回每个索引的架构以减轻索引的识别。

但同样:我也会在同一个模式中创建索引和表。

于 2011-09-01T06:51:48.357 回答
1

我建议您直接查询 Oracle 字典表,但从以下开始:

select * from dba_indexes

使用该视图几乎可以轻松获得所需的信息。

但是,访问 dba_ 表和视图需要用户具有特殊权限,但由于您不想将 DBA 权限授予所有人,您可以:

grant select any dictionary to username

连接为 system 或 sys 以便所选用户可以查询字典。

以防万一您想探索 Oracle 的字典,请尝试:

select * from dict

此致。

于 2011-09-01T06:09:18.700 回答