【问题标题】:oracle sql dynamically select columns using a parameter tableoracle sql 使用参数表动态选择列
【发布时间】:2020-08-29 23:11:18
【问题描述】:

我在 oracle 中有一个包含 10 列的表,例如表 A,其中包含 col_1、col_2、col_3 等。我还有另一个表,表 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 中完成此操作,则可能但更棘手。
  • 嗨 Jon,我的目标是根据另一个表中存在的列动态生成数据集。我对 plsql 不是很熟悉,我正在使用一个支持 sql 代码的应用程序。目前,我正在尝试在 with 子句(oracle 12c 增强)中的 plsql 代码/函数中实现 Tejash 建议的动态 sql 并实现我想要的......请告诉我这种方法是否有效?并指引我正确的方向。
  • 在下面查看我的答案。

标签: sql oracle dynamic-sql


【解决方案1】:

引用游标可用于创建动态列。许多语言和应用程序都支持引用光标,如果您添加有关系统的一些详细信息,有人可能会确切地知道如何将它们集成到您的环境中。

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

示例架构

--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;
/

【讨论】:

    【解决方案2】:

    我认为我们应该去 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;
    

    【讨论】:

      【解决方案3】:

      您需要使用动态查询。

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

      【讨论】:

      • 我收到 ORA-01489:字符串连接的结果太长错误与 LISTAGG
      猜你喜欢
      • 1970-01-01
      • 2012-05-01
      • 2021-08-26
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多