使用参数表动态选择列的ORACLE sql

问题描述 投票:0回答:1

我在oracle中有一个表,有10列,比如表A,有col_1,col_2,col_3等。我有另一个表B,表B中的行有表A中的列名co1_1,col_2,col_3。表B中的行可以不一样。

TABLE A

COL1 COL2 COL3 COL4 COL5 COL6 COL7 COL8 COL9 COL10 

TABLE B
COL1
COL2
COL3

我想写一个oracle sql查询,根据表B中的列名(行)动态地获取选择列名。

如果表B中有3条记录有相应的列名,那么我的查询应该是这样的。

从A中选择col_1, col_2, col_3。

如果表B有4条记录,那么我的查询应该动态地改变为下面的内容。

select col_1, col_2, col_3, col_4  from A
sql oracle dynamic-sql
1个回答
2
投票

你需要使用动态查询。

'SELECT '
|| (SELECT LISTAGG(COLNAME, ',') WITHIN GROUP (ORDER BY COLNAME) FROM TABLEB)
|| ' FROM TABLEA'

0
投票

我认为我们应该到ALL_TAB_COLUMNS表中查找列名,像这样。

SELECT 
    'SELECT ' 
     ||
    (SELECT  LISTAGG( y.COLNAME, ',') WITHIN GROUP (ORDER BY Y.COLNAME)
     FROM TABLE_B x,ALL_TAB_COLUMNS y
     where x.COLNAME=Y.COLUMN_NAME )  
     || 
     ' FROM Table_A' script 
FROM DUAL;

0
投票

可以使用ref游标来创建动态列。许多语言和应用程序都支持ref游标,如果你添加一些关于你的系统的细节,有人可能知道如何在你的环境中准确地集成它们。

下面是一个简单的例子,说明如何创建一个返回 ref 游标的函数。如何调用它取决于你的系统。

示例模式

--drop table a;
--drop table b;

create table a as
select 1 col1, 2 col2, 3 col3, 4 col4, 5 col5, 6 col6, 7 col7, 8 col8, 9 col9, 10 col10
from dual;

create table b as
select 'COL1' column_name from dual union all
select 'COL2' column_name from dual union all
select 'COL3' column_name from dual;

功能

create or replace function get_dynamic_results return sys_refcursor is
    v_cursor sys_refcursor;
    v_column_list varchar2(4000);
begin
    --Split this into multiple SELECTS if you get an error like:
    -- ORA-01489: result of string concatenation is too long error
    select listagg(column_name, ',') within group (order by column_name) columns
    into v_column_list
    from b;

    open v_cursor for 'select '||v_column_list||' from a';

    return v_cursor;
end;
/
© www.soinside.com 2019 - 2024. All rights reserved.