Как получить все индексы для таблицы в Oracle через JDBC, даже если они принадлежат разным пользователям? - PullRequest
2 голосов
/ 23 августа 2011

Да, я знаю о DatabaseMetadata.getIndexInfo, но, похоже, он не выполняет то, что я хочу.

У меня есть два пользователя / схемыдавайте назовем их A и B.

В A есть таблица с именем TAB.Пользователь B создал индекс для A.TAB, назовем этот индекс IND.

Информация, которую я хочу , такова: какие индексы есть в таблице TABв схеме A (он же с владельцем A).Мне плевать на владельца индексов, просто они на этом конкретном столе.

Экспериментируя с getIndexInfo Я обнаружил следующие вещи:

  • первыйаргумент catalog, похоже, полностью игнорируется драйвером Oracle JDBC.
  • второй аргумент schema ограничивает , какие статистические данные таблицы возвращаются и владелец индекса
  • unique и approximate делают (примерно) то, что должны (за исключением того, что при approximate=false фактически выполняется оператор статистики обновления).

Отследив SQL, который драйвер JDBC выполняет на 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. executeэтот SQL напрямую (используя executeQuery()).Я бы предпочел не опускаться до этого уровня, если только это не является абсолютно неизбежным.

Ни один из этих обходных путей не выглядит мне особенно приятным, но если ничего не работает, мне, возможно, придется вернуться к прямому SQLвыполнение.

И база данных, и драйвер JDBC находятся по адресу 11.2.0.2.0.

Так что в основном мои вопросы:

  1. Это ошибка вДрайвер JDBC, или есть какая-то логика, о которой я не знаю?
  2. Существует ли простой и достаточно переносимый способ заставить Oracle предоставлять мне нужную информацию?

Ответы [ 2 ]

1 голос
/ 01 сентября 2011

всегда создайте индекс и таблицу в одной и той же схеме (т. Е. Пусть у них будет один и тот же владелец).К сожалению, это не всегда вариант.

Это был бы мой предпочтительный способ сделать это.

Запрос со схемой, равной нулю.Это было бы ужасно, как только две схемы содержали одно и то же имя таблицы (потому что нет способа узнать, для какой таблицы (то есть, у какого владельца таблицы) данная схема)

Конечно, вы можете найтиэто потому, что результирующий набор, возвращаемый getIndexInfo (), содержит правильную схему для каждой таблицы.Но вы не можете узнать, в какой схеме находится index .

выполнить этот SQL напрямую

Я бы фактически использовал модифицированную версию этого запроса, которая также возвращает схему для каждого индекса, чтобы облегчить идентификацию индекса.

Но опять же: я бы тоже создал индекс и таблицу в одной схеме.

1 голос
/ 01 сентября 2011

Я предлагаю вам сделать запрос непосредственно к таблицам словаря Oracle, НО начните с:

select * from dba_indexes

Используя это представление, вы получите почти тривиальную информацию, которая вам нужна.

Однако доступ кТаблицы и представления dba_ требуют, чтобы у пользователя были особые привилегии, но, поскольку вы не хотите предоставлять привилегии администратора БД всем, вы можете просто:

grant select any dictionary to username

подключиться как система или sys, чтобы выбранный пользователь могзапросить словарь.

На всякий случай, если вы хотите изучить словарь Oracle, попробуйте:

select * from dict

С уважением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...