在以下查询(存储过程内部(oracle。。
SELECT
index_name,
index_description,
ltrim(sys_connect_by_path(index_keys,','),',') as Index_Keys,
include_cols,
index_filter,
data_compression,
allow_page_locks,
table_name,
index_type
from
(
Select t.*,
row_number() over (partition by INDEX_NAME order by COLUMN_POSITION) as rn
from
(
SELECT
di.index_name AS "INDEX_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'clustered'
ELSE 'nonclustered'
END
||
CASE
WHEN di.uniqueness = 'UNIQUE' AND
substr (
di.index_name,
1,
3
) = 'PK_' THEN ', unique, primary key'
WHEN di.uniqueness = 'UNIQUE' THEN ', unique'
END
||
CASE
WHEN di.uniqueness = 'NONUNIQUE' THEN ''
ELSE ''
END
||
' located on PRIMARY' AS "INDEX_DESCRIPTION",
ci.column_name AS "INDEX_KEYS",
NULL AS "INCLUDE_COLS",
NULL AS "INDEX_FILTER",
NULL AS "DATA_COMPRESSION",
NULL AS "ALLOW_PAGE_LOCKS",
di.table_name AS "TABLE_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'CLUSTERED'
ELSE 'NONCLUSTERED'
END
AS "INDEX_TYPE",ci.column_position
FROM
dba_indexes di
JOIN dba_ind_columns ci
ON ci.index_owner = di.owner AND
ci.index_name = di.index_name
WHERE
di.table_owner = '****' AND
di.table_name = '******' AND
partitioned = 'NO'
UNION ALL
SELECT
di.index_name AS "INDEX_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'clustered'
ELSE 'nonclustered'
END
||
CASE
WHEN di.uniqueness = 'UNIQUE' AND
substr (
di.index_name,
1,
3
) = 'PK_' THEN ', unique, primary key'
WHEN di.uniqueness = 'UNIQUE' THEN ', unique'
END
||
CASE
WHEN di.uniqueness = 'NONUNIQUE' THEN ''
ELSE ''
END
||
' located on PRIMARY' AS "INDEX_DESCRIPTION",
ci.column_name AS "INDEX_KEYS",
NULL AS "INCLUDE_COLS",
NULL AS "INDEX_FILTER",
NULL AS "DATA_COMPRESSION",
NULL AS "ALLOW_PAGE_LOCKS",
di.table_name AS "TABLE_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'CLUSTERED'
ELSE 'NONCLUSTERED'
END
AS "INDEX_TYPE",ci.column_position
FROM
dba_indexes di
JOIN dba_ind_partitions dip
ON dip.index_owner = di.owner AND
dip.index_name = di.index_name
JOIN dba_ind_columns ci
ON ci.index_owner = di.owner AND
ci.index_name = di.index_name
WHERE
di.table_owner = '*******' AND
di.table_name = '******' AND
di.partitioned = 'YES' AND
dip.composite != 'YES'
UNION ALL
SELECT
di.index_name AS "INDEX_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'clustered'
ELSE 'nonclustered'
END
||
CASE
WHEN di.uniqueness = 'UNIQUE' AND
substr (
di.index_name,
1,
3
) = 'PK_' THEN ', unique, primary key'
WHEN di.uniqueness = 'UNIQUE' THEN ', unique'
END
||
CASE
WHEN di.uniqueness = 'NONUNIQUE' THEN ''
ELSE ''
END
||
' located on PRIMARY' AS "INDEX_DESCRIPTION",
ci.column_name AS "INDEX_KEYS",
NULL AS "INCLUDE_COLS",
NULL AS "INDEX_FILTER",
NULL AS "DATA_COMPRESSION",
NULL AS "ALLOW_PAGE_LOCKS",
di.table_name AS "TABLE_NAME",
CASE
WHEN di.index_type = 'IOT - TOP' THEN 'CLUSTERED'
ELSE 'NONCLUSTERED'
END
AS "INDEX_TYPE",ci.column_position
FROM
dba_indexes di
JOIN dba_ind_partitions dip
ON dip.index_owner = di.owner AND
dip.index_name = di.index_name
JOIN dba_ind_subpartitions dis
ON dis.index_owner = di.owner AND
dis.index_name = di.index_name AND
dis.partition_name = dip.partition_name
JOIN dba_ind_columns ci
ON ci.index_owner = di.owner AND
ci.index_name = di.index_name
WHERE
di.table_owner = '***' AND
di.table_name = '*****' AND
di.partitioned = 'YES' AND
dip.composite = 'YES' ) t
)
where connect_by_isleaf = 1
connect by index_name = prior index_name
and rn = prior rn+1
start with rn =1 ;
它给出以下输出。。
[在此输入图像描述][1]
AI_TESTORACLE_TEMP_27977和AI_TESTORACLE_TEMP_27978的索引键当前显示函数索引的column_name,即dba_ind_columns中的SYS_NC00023$和SYS_NC00024$;TestInt,lower(TestShortString(";以及";TestSmallInt,UPPER(TestShortString(";。。。。这是列表达式,可以从dbacolexpressions视图派生。。
Name Null? Type
----------------------------------------------------------------------- -------- -----------------------------
INDEX_OWNER NOT NULL VARCHAR2(128)
INDEX_NAME NOT NULL VARCHAR2(128)
TABLE_OWNER NOT NULL VARCHAR2(128)
TABLE_NAME NOT NULL VARCHAR2(128)
COLUMN_EXPRESSION LONG
COLUMN_POSITION NOT NULL NUMBER
SQL> desc dba_ind_Columns;
Name Null? Type
----------------------------------------------------------------------- -------- ----------------------
INDEX_OWNER NOT NULL VARCHAR2(128)
INDEX_NAME NOT NULL VARCHAR2(128)
TABLE_OWNER NOT NULL VARCHAR2(128)
TABLE_NAME NOT NULL VARCHAR2(128)
COLUMN_NAME VARCHAR2(4000)
COLUMN_POSITION NOT NULL NUMBER
COLUMN_LENGTH NOT NULL NUMBER
CHAR_LENGTH NUMBER
DESCEND VARCHAR2(4)
COLLATED_COLUMN_ID NUMBER
只需要在这个查询中做一些小的更改,就可以将列表达式而不是列名输出为index_keys,仅用于函数索引(这有点棘手(。。在其他列中休息无变化。。寻求这里所有专家的帮助。。
INDEX_TYPE作为基于函数的NORMAL或NORMAL可以从DBA_INDEXES 获取
SQL> select column_Expression from dba_ind_expressions where table_name='TESTORACLE_TEMP' AND TABLE_OWNER='ROLLOUT';
COLUMN_EXPRESSION
--------------------------------------------------------------------------------
LOWER("TESTSHORTSTRING")
UPPER("TESTSHORTSTRING")
SQL> select column_name from dba_ind_columns where table_owner='ROLLOUT' and table_name='TESTORACLE_TEMP';
COLUMN_NAME
----------------------------------------------------------------------------------------------------------------
KEYTESTORACLE
TESTTINYINT
TESTSMALLINT
TESTUNIQUEIDENTIFIER
TESTINT
SYS_NC00023$
TESTSMALLINT
SYS_NC00024$
UPDDATE
9 rows selected.
[![在此输入图像描述][2]][2]
添加index_keys列(当前输出和预期([1] :https://i.stack.imgur.com/fsg0z.png[2] :https://i.stack.imgur.com/SeewU.jpg
使用user_ind_expressions
进行左联接。如果不为null,则从该表中获取值,否则从user_index_columns
中获取值。然后您可以进行分层查询,或者listagg()
会更好。
一个问题。Column_expression
是长数据类型的(至少我看到它是这样的形式(,所以我做了一个简单的函数将它转换为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
正如您所看到的,ID取自user_ind_columns
,其他密钥来自user_ind_expressions
。