Как сделать так, чтобы предложение 'order by' в функции Oracle использовало переменную, представляющую числовой индекс? - PullRequest
2 голосов
/ 15 сентября 2011

Я эмулирую DESCRIBE имя таблицы , доступное в Sqlplus, чтобы сделать похожую функциональность доступной через обычный sql.

У меня есть объекты / функции, перечисленные ниже, и это работает - за исключением предложения order_param. Это в основном игнорируется. Я могу вызвать функцию через:

select * from table(describe('my_table',1));

или

select * from table(describe('my_table',2));

и это приводит к тому же порядку.

Если я заменю order by order_param на order by 1 или order by 2 в предложении sql в функции, он будет работать как положено.

Должен быть более эффективный способ заставить это работать, чем использование динамического SQL (или функция должна фактически выбирать между 2 предложениями SQL).

CREATE OR REPLACE TYPE table_description as object (
  column_name varchar2(30),
  column_id   number, 
  data_type   varchar2(30),
  nullable    varchar2(1)
);

CREATE OR REPLACE TYPE table_description_type as table of table_description;

CREATE OR REPLACE FUNCTION describe (tname IN VARCHAR2, order_param in NUMBER default 2) RETURN table_description_type AS
-- function to describe a table
-- eg. use via select * from table(describe('table_name'));

  v_ret table_description_type;

BEGIN

 select cast(multiset(
    select column_name, data_type || data_suff "Data Type", nullable from (
      select column_name, column_id, data_type, 
      case when data_type = 'DATE' then '' else '(' ||  
        case when data_type in ('CHAR','VARCHAR2','NCHAR','NVARCHAR') 
        then to_char(char_length) else data_precision || ', ' || data_scale end || ')'
      end data_suff, 
      nullable, data_default, num_nulls, last_analyzed, avg_col_len 
      from all_tab_columns where table_name = upper(tname)
      order by order_param
    )
 ) as table_description_type) into v_ret from dual;

 return v_ret;

END;
/

1 Ответ

4 голосов
/ 15 сентября 2011

Вы не можете сделать это так, как вы пытаетесь. Чтобы предложение order интерпретировало числовое значение как ссылку на столбец, число должно присутствовать при анализе запроса. Поскольку вы связываете переменную в, она всегда будет интерпретировать ваш параметр как значение, а не ссылку на столбец. Чтобы это исправить, вам нужно логически изменить предложение order by, чтобы выбрать столбец на основе значения:

order by case order_param 
         when 1 then column_name 
         else data_type || data_suff
         end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...