在Oracle 12c中动态构建select语句

时间:2014-06-02 15:27:57

标签: sql oracle select dynamic clob

之前我已经发布了类似的问题,但这个问题的解决方案似乎完全不同,因此我希望这不符合重新发布的条件。

所需物品: 我在名为SETUPS的表中有2列,其中包含以下列:

ID INTEGER NOT NULL RPT_SCRIPT CLOB NOT NULL

RPT_SCRIPT在每条记录中都有select语句。以下是clob列WHERE ID = 1中的声明:

SELECT ID,
 Title,
 Desc,
 Type,
 LVL_CNT,
 TYPE_10 VALUE_10,
 TYPE_9 VALUE_9,
 TYPE_8 VALUE_8,
 TYPE_7 VALUE_7,
 TYPE_6 VALUE_6,
 TYPE_5 VALUE_5,
 TYPE_4 VALUE_4,
 TYPE_3 VALUE_3,
 TYPE_2 VALUE_2,
 TYPE_1 VALUE_1
  FROM SCHEMA.TABLE
WHERE ID = 1;

目前我正在为所有记录手动编写这些select语句。

SETUPS.ID映射到另一个主表META.ID以构建select语句。

带有模式TYPE_%的列名称,即TYPE_1,来自META表;表格中共有20列具有此模式,但在此示例中,我仅使用了10列,因为META.LVL_CNT = 10。同样,如果META.LVL_CNT = 5,则只选择TYPE_1TYPE_2TYPE_3TYPE_4TYPE_5列。

列别名,即VALUE_1,是来自相应列的值META.ID = 1(如本例所示)。 将始终提供ID,因此可用于查询表META

修改 来自META表的列别名将永远不会有我在示例中显示的模式,但使用LVL_CNT,在运行时我们将知道列数。我尝试使用@ Asfakul提供的逻辑并使用动态检索的列名构建动态sql但是在使用EXECUTE IMMEDIATE INTO时我意识到我不知道将检索多少列,因此无法动态生成使用此方法的别名。

需要使用以上信息自动构建此选择状态的方法..我该如何实现?请提供任何示例。

2 个答案:

答案 0 :(得分:2)

您可以将此作为基础

declare
    upper_level number;
    t_sql varchar2(1000);
    l_sql varchar2(1000);
begin
    select lvl_cnt into upper_level from 
    SETUPS S,META S
    where s.id=m.id

    l_sql:='SELECT ID,
     Title,
     Desc,
     Type,'||
     upper_level


    for lvl in 1..upper_level
     loop
         t_sql:=t_sql||'type_'||lvl||','
     end loop;
     l_sql:=l_sql||t_sql
     l_sql:=rtrim(l_sql,',');
     l_sql:=l_sql||' FROM SCHEMA.TABLE
    WHERE ID = 1;';

end

答案 1 :(得分:0)

我推荐这种方法,如果你已经知道如何构建动态SQL,那么使用这个概念来构建你的查询:

    SELECT 'TYPE_' || LEVEL
      FROM DUAL
CONNECT BY LEVEL <= 10 --10 could be a variable