Сделать левое соединение с user_ind_expressions
. Возьмите значение из этой таблицы из этой таблицы, если оно не равно нулю, в противном случае из user_index_columns
. Тогда вы можете сделать свой иерархический запрос, или, может быть, listagg()
будет лучше.
Одна проблема. Column_expression
имеет длинный тип data_type (по крайней мере, я вижу его в такой форме), поэтому я сделал простую функцию для преобразования его в varchar (вы можете улучшить его, пожалуйста, прочитайте соответствующие статьи, например, на сайте asktom).
create or replace function
get_expr(i_tn in varchar2, i_in in varchar2, i_cp in number) return varchar2 as
l_data long;
begin
select column_expression into l_data from user_ind_expressions
where table_name = i_tn and index_name = i_in and column_position = i_cp;
return substr(l_data, 1, 4000);
end;
Это мои тестовые данные и запрос:
create table emp(id primary key, fname, lname, dept) as (
select 707, 'Pete', 'Griffin', 'Sales' from dual);
create index idx_emp1 on emp(lower(dept));
create index idx_emp2 on emp(upper(lname), upper(fname));
и запрос:
select index_name,
ltrim(sys_connect_by_path(index_keys,','),',') as Index_Keys
from (
select t.*, row_number() over (partition by index_name order by column_position) as rn
from (
select index_name, column_name, column_position,
nvl(get_expr(table_name, index_name, column_position), column_name) as index_keys
from user_indexes di
join user_ind_columns ci using (table_name, index_name)
left join user_ind_expressions using (table_name, index_name, column_position)
where table_name = 'EMP') t )
where connect_by_isleaf = 1
connect by index_name = prior index_name and rn = prior rn+1
start with rn = 1
и результат:
INDEX_NAME INDEX_KEYS
--------------- --------------------------------
IDX_EMP1 LOWER("DEPT")
IDX_EMP2 UPPER("LNAME"),UPPER("FNAME")
SYS_C00148175 ID
Как видите Идентификатор взят из user_ind_columns
, остальные ключи - из user_ind_expressions
.