Но я бы хотел, чтобы он возвращал только одну строку на индекс. В случае нескольких столбцов столбец INDEX_KEYS должен отражать все столбцы в виде списка через запятую.
Вы можетепопробуйте это в Oracle 11g :
CREATE OR REPLACE PROCEDURE test_1 (
p_table_owner IN VARCHAR2,
p_table_name IN VARCHAR2,
p_result OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_result FOR
SELECT
index_name,
index_description,
LISTAGG (index_keys,',') WITHIN GROUP ( ORDER BY index_name ) "Index_Keys",
include_cols,
index_filter,
data_compression,
allow_page_locks,
table_name,
index_type
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"
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 = 'CON$' AND
di.table_name = 'CON$' 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"
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 = 'CON$' AND
di.table_name = 'CON$' 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"
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 = 'CON$' AND
di.table_name = 'CON$' AND
di.partitioned = 'YES' AND
dip.composite = 'YES' )
group BY index_name,index_description,INCLUDE_COLS,index_filter ,data_compression, allow_page_locks, table_name,index_type ;
END;
Обратите внимание, что я использовал table_name
как 'CON$'
.Замените его на table_name
моим именем table_name
РЕДАКТИРОВАТЬ:
Любая помощь в том, чтобы он также работал с версиями 10g?только что узнал, что нам это тоже может понадобиться ..
В Oracle 10g вы можете сделать следующее:
CREATE OR REPLACE PROCEDURE test_1 (
p_table_owner IN VARCHAR2,
p_table_name IN VARCHAR2,
p_result OUT SYS_REFCURSOR
)
AS
BEGIN
OPEN p_result FOR
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 INDEX_NAME) 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"
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 = 'CON$' AND
di.table_name = 'CON$' 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"
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 = 'CON$' AND
di.table_name = 'CON$' 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"
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 = 'CON$' AND
di.table_name = 'CON$' 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 ;
End;