在 18c 及更高版本中,您可以创建多态表函数以根据模式动态选择列。在 12c 及以下,您需要使用 Oracle 数据盒在 SQL 中创建动态 SQL。两种解决方案都需要 PL/SQL,但最终结果的外观和行为就像常规 SQL。在实践中,您可能希望在应用层而不是数据库中解决这些动态问题。例如,如果您正在构建 Excel 电子表格,大多数 Oracle-Excel API 都允许将查询作为字符串传递。
18c及以上-多态表函数
首先,创建一个包,用于标识表中的哪些列要通过 SQL 语句传递,以及哪些列要忽略。多态表函数有很多不寻常的语法,所以下面的代码乍一看并没有多大意义。
create or replace package percent_cols as
function percent_cols(tab in table) return table pipelined row polymorphic using percent_cols;
function describe(tab in out dbms_tf.table_t) return dbms_tf.describe_t;
end percent_cols;
/
create or replace package body percent_cols as
function describe (tab in out dbms_tf.table_t) return dbms_tf.describe_t
as
begin
for i in 1 .. tab.column.count() loop
if tab.column(i).description.name like '%PERCENT\_%' escape '\' then
tab.column(i).pass_through := true;
else
tab.column(i).pass_through := false;
end if;
end loop;
return null;
end;
end percent_cols;
/
创建一些示例表来测试包:
create table test1(a number, percent_1 number);
insert into test1 values(1, 1);
create table test2(percent_1 number, percent_2 number);
insert into test2 values(2, 2);
create table test3(a number);
insert into test3 values(3);
以下示例查询仅显示 PERCENT% 列。您可能需要为没有任何匹配列的表添加一些异常处理。
SQL> select * from percent_cols(test1);
PERCENT_1
----------
1
SQL> select * from percent_cols(test2);
PERCENT_1 PERCENT_2
---------- ----------
2 2
SQL> select * from percent_cols(test3);
select * from percent_cols(test3)
*
ERROR at line 1:
ORA-30732: table contains no user-visible columns
12c 及以下 - Oracle 数据磁带
数据盒让我们以许多有趣的方式扩展 Oracle,但界面很难使用。与其创建自己的 PL/SQL 类型和函数,不如从 my open source project 开始。
此解决方案需要比多态表函数更多的代码,但它的优势在于将更多逻辑保留在常规 SQL 中 - 您可以在表函数中看到单个数据字典查询,而不是将其隐藏在 PL/SQL 后面.
select * from table(method4.dynamic_query(
q'[
select 'select '||listagg(column_name, ',') within group (order by column_id)||' from '||table_name v_sql
from all_tab_columns
where table_name = 'TEST2'
and column_name like 'PERCENT_%'
group by table_name
]'
));
PERCENT_1 PERCENT_2
---------- ----------
2 2