Oracle 当索引为DESC时获得索引列的名称

    xiaoxiao2021-03-26  28

    这是一个容易被忽视的问题。

    [sql]  view plain  copy   -- 建表和索引  CREATE TABLE t1  (     a   INT,     b   INT  );    CREATE INDEX IDX1 ON T1 (a DESC, b DESC);  CREATE INDEX IDX2 ON T1 (a, b);  CREATE INDEX IDX3 ON T1 (a ASC, b DESC);    -- 直接查询user_ind_columns  SELECT index_name, column_name, descend    FROM user_ind_columns   WHERE table_name = 'T1';   结果如下: INDEX_NAME              COLUMN_NAME           DESCEND ------------------------------ ------------------------------        -------- IDX1                           SYS_NC00004$            DESC IDX1                           SYS_NC00005$            DESC IDX2                           A                                   ASC IDX2                           B                                   ASC IDX3                           A                                   ASC IDX3                           SYS_NC00005$            DESC 可见当索引列定义为DESC时,user_ind_columns.COLUMN_NAME并不能正确显示列名。 [sql]  view plain  copy   -- 查询user_ind_expressions  SELECT *    FROM user_ind_expressions   WHERE table_name = 'T1';   结果如下: INDEX_NAME                     TABLE_NAME                     COLUMN_EXPRESSION              COLUMN_POSITION ------------------------------ ------------------------------ ------------------------------ --------------- IDX1                           T1                             "A"                                       1 IDX1                           T1                             "B"                                       2 IDX3                           T1                             "B"                                       2 从user_ind_expressions视图可以查询到索引列名。Oracle把DESC定义的索引作为函数索引,所以看到的是加了引号的列名,被当做函数表达式。 从以上分析得知,可以关联user_ind_columns和user_ind_expressions查询出所有索引列名称。这时又遇到一个问题,COLUMN_EXPRESSION列是LONG类型的,不能使用普通的函数进行处理,需要先建立一个转换函数,把LONG转换成VARCHAR。 [sql]  view plain  copy   CREATE OR REPLACE FUNCTION long_2_varchar (     p_index_name        IN user_ind_expressions.index_name%TYPE,     p_table_name        IN user_ind_expressions.table_name%TYPE,     p_COLUMN_POSITION   IN user_ind_expressions.table_name%TYPE)     RETURN VARCHAR2  AS     l_COLUMN_EXPRESSION   LONG;  BEGIN     SELECT COLUMN_EXPRESSION       INTO l_COLUMN_EXPRESSION       FROM user_ind_expressions      WHERE     index_name = p_index_name            AND table_name = p_table_name            AND COLUMN_POSITION = p_COLUMN_POSITION;       RETURN SUBSTR (l_COLUMN_EXPRESSION, 1, 4000);  END;  /    -- 现在可以查询列名了    SELECT a.INDEX_NAME,           REPLACE (              DECODE (                 descend,                 'DESC', long_2_varchar (b.index_name,                                         b.table_NAME,                                         b.COLUMN_POSITION),                 a.column_name),              '"',              '')              COLUMN_NAME,           a.COLUMN_POSITION,           DESCEND      FROM user_ind_columns a           LEFT JOIN user_ind_expressions b              ON a.index_name = b.index_name AND a.table_name = b.table_name     WHERE a.table_name = 'T1'  ORDER BY INDEX_NAME, column_position;    -- 再行列转置把一个索引的多行转成一行    SELECT INDEX_NAME,           MAX (DECODE (COLUMN_POSITION, 1, COLUMN_NAME || ' ' || DESCEND, NULL))              c1,           MAX (DECODE (COLUMN_POSITION, 2, COLUMN_NAME || ' ' || DESCEND, NULL))              c2,           MAX (DECODE (COLUMN_POSITION, 3, COLUMN_NAME || ' ' || DESCEND, NULL))              c3,           MAX (DECODE (COLUMN_POSITION, 4, COLUMN_NAME || ' ' || DESCEND, NULL))              c4,           MAX (DECODE (COLUMN_POSITION, 5, COLUMN_NAME || ' ' || DESCEND, NULL))              c5      FROM (  SELECT a.INDEX_NAME,                     REPLACE (                        DECODE (                           descend,                           'DESC', long_2_varchar (b.index_name,                                                   b.table_NAME,                                                   b.COLUMN_POSITION),                           a.column_name),                        '"',                        '')                        COLUMN_NAME,                     a.COLUMN_POSITION,                     DESCEND                FROM user_ind_columns a                     LEFT JOIN                     user_ind_expressions b                        ON     a.index_name = b.index_name                           AND a.table_name = b.table_name               WHERE a.table_name = 'T1'            ORDER BY INDEX_NAME, column_position)  GROUP BY INDEX_NAME;  
    转载请注明原文地址: https://ju.6miu.com/read-350279.html

    最新回复(0)