SPROC应该也兼容11g以下的版本。
创建了此过程,但是它为基于多列的索引显示2行。我想将其显示为一行,并用逗号分隔值
当前,如果我在表上执行此操作(以获取索引信息)。它向我显示2行索引(多列),但我希望每个索引仅返回一行。如果有多列,则INDEX_KEYS列应将所有列反映为逗号分隔的列表。
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
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;
答案 0 :(得分:1)
但是我希望每个索引只返回一行。 多列,则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;
答案 1 :(得分:1)
使用LISTAGG
和GROUP BY
:
Oracle设置:
CREATE TABLE table_name (
id NUMBER CONSTRAINT PK_TABLE_NAME__ID PRIMARY KEY,
value NUMBER,
other1 NUMBER,
other2 NUMBER,
CONSTRAINT U_TABLE_NAME__OTHER1_OTHER2 UNIQUE ( other1, other2 )
);
查询:
(注1:dbfiddle不允许访问dba_*
表,因此下面的查询使用user_*
表,而没有注释掉适用于dba_
版本的部分。)< / i>
(注2:在您不同的UNION
ed查询的输出之间似乎没有功能上的区别,因此我删除了di.partitioned
上的过滤器。如果存在非显而易见的则可以将它们放回去并在外部查询中执行LISTAGG
分组。)
select di.index_name as "INDEX_NAME",
CASE WHEN di.index_type='IOT - TOP' THEN 'clustered' ELSE 'nonclustered' END
||
CASE WHEN di.uniqueness = 'UNIQUE' THEN ', unique' END
||
CASE WHEN cons.constraint_type = 'P' THEN ', primary key' END
||
' located on PRIMARY' AS "INDEX_DESCRIPTION",
LISTAGG( ci.column_name, ',' ) WITHIN GROUP ( ORDER BY ci.COLUMN_POSITION ) 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*/user_indexes di
INNER JOIN /*dba*/user_constraints cons
ON ( cons.owner = di.table_owner
AND cons.table_name = di.table_name
-- AND cons.index_owner = di.owner
AND cons.index_name = di.index_name
)
join /*dba*/user_ind_columns ci
on ci.index_name = di.index_name
where di.table_name = 'TABLE_NAME'
--and di.table_owner = 'OWNER'
GROUP BY di.table_name, di.index_name, cons.constraint_type, di.uniqueness, di.index_type
输出:
INDEX_NAME | INDEX_DESCRIPTION | INDEX_KEYS | INCLUDE_COLS | INDEX_FILTER | DATA_COMPRESSION | ALLOW_PAGE_LOCKS | TABLE_NAME | INDEX_TYPE :-------------------------- | :--------------------------------------------------- | :------------ | :----------- | :----------- | :--------------- | :--------------- | :--------- | :----------- PK_TABLE_NAME__ID | nonclustered, unique, primary key located on PRIMARY | ID | null | null | null | null | TABLE_NAME | NONCLUSTERED U_TABLE_NAME__OTHER1_OTHER2 | nonclustered, unique located on PRIMARY | OTHER1,OTHER2 | null | null | null | null | TABLE_NAME | NONCLUSTERED
db <>提琴here