- Criando uma tabela da seguinte forma:
CREATE TABLE "HOTEL3"
( "NAMEX" VARCHAR2(4000 CHAR),
"CITY" VARCHAR2(4000 CHAR),
"PRICE" NUMBER,
"ID" VARCHAR2(50 BYTE) DEFAULT sys_guid()
);
- Criando um índice da seguinte forma:
CREATE INDEX "IDX_HOTEL3_CITY_NAME" ON "HOTEL3" ("CITY" ASC, "NAMEX" DESC);
- Consultando as informações do índice:
SELECT *
FROM all_ind_columns ic
WHERE ic.index_owner = 'FOO'
AND ic.table_name = 'HOTEL3'
ORDER BY ic.column_position;
Estou obtendo o resultado abaixo (csv)
"INDEX_OWNER","INDEX_NAME","TABLE_OWNER","TABLE_NAME","COLUMN_NAME","COLUMN_POSITION","COLUMN_LENGTH","CHAR_LENGTH","DESCEND","COLLATED_COLUMN_ID"
"FOO","IDX_HOTEL3_CITY_NAME","FOO","HOTEL3","CITY",1,4000,4000,"ASC",
"FOO","IDX_HOTEL3_CITY_NAME","FOO","HOTEL3","SYS_NC00005$",2,2000,0,"DESC",
Observe o segundo registro; COLUMN_NAME
é SYS_NC00005$
em vez de NAMEX
.
Aqui estão algumas notas laterais. Após a etapa 1, se você consultar, all_tab_cols
obterá todas as 4 colunas. No entanto, após a etapa 2, all_tab_cols
agora há uma entrada adicional - o mesmo nome mostrado acima do resultado da consulta. Isso pode ser exagerado; mas o ID
campo definido DEFAULT
pode ser o motivo, após a etapa 2, all_tab_cols
ter essa entrada estranha.
Então, qual consulta posso emitir para obter as informações de índice corretas?
PS: o servidor oracle é 19c, eu acho.
É assim que um índice em uma coluna definida com ordem decrescente é definido.
Você pode encontrar a expressão real na
COLUMN_EXPRESSION
coluna daALL_IND_EXPRESSIONS
exibição.Quando você definiu
NAMEX
comoDESC
, o Oracle cria um índice baseado em função usandoSYS_OP_DESCEND
umaRAW
coluna oculta internamente que você pode ver emall_tab_cols
(não emall_tab_columns
). O índice está nestaRAW
coluna que tem um nome gerado pelo sistema.all_ind_expressions
mostrará a expressão que será passada para essas funções, indicando o nome da coluna.Sempre que você tiver qualquer tipo de índice baseado em função, você deve ir
*_ind_expressions
para obter a definição real e trocar a coluna nomeada pelo sistema por esta expressão para representar o que você espera.Agora, isso não pode ser feito em SQL porque isso exigiria trabalhar com LONGs, com os quais o SQL pode fazer muito pouco. Existe uma solução alternativa, porém usando PL/SQL:
Agora você pode usar
all_ind_expressions_ext
em seu SQL e usar a expressão em qualquer função que desejar (CASE
,REPLACE
,WHERE
cláusula,LISTAGG
, qualquer coisa).