我正在模仿Sqlplus中可用的DESCRIBE tablename,以通过常规sql提供类似的功能。
我有下面列出的对象/函数,它有效 - 除了order_param
子句。它基本上被忽略了。我可以通过以下方式调用该函数:
select * from table(describe('my_table',1));
或
select * from table(describe('my_table',2));
会产生相同的排序。
如果我在函数的sql子句中用order by order_param
或order by 1
替换order by 2
,它会按预期工作。
除了使用动态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;
/
答案 0 :(得分:4)
你不能按照你想要的方式做到这一点。为了使order
子句将数值解释为列引用,在解析查询时必须存在该数字。由于您将变量绑定在中,因此它始终将您的参数解释为值,而不是列引用。要解决此问题,您需要在逻辑上更改order by
子句,以根据值选择列:
order by case order_param
when 1 then column_name
else data_type || data_suff
end