简体   繁体   中英

Dynamically build select statement in Oracle 12c

I have posted the similar question before but the solution to this question seems like it will be completely different, thus I hope this does not qualify for a repost.

Req: I have 2 columns in a table named SETUPS with the following columns:

ID INTEGER NOT NULL RPT_SCRIPT CLOB NOT NULL

RPT_SCRIPT has select statements in each record. Below is a statement in the clob column 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;

Currently I am writing these select statements manually for all records.

SETUPS.ID is mapped to another master table META.ID in order to build the select statement.

The column names with pattern TYPE_% , ie TYPE_1 , come from the META table; there are total of 20 columns in the table with this pattern but in this example I've used only 10 because META.LVL_CNT = 10 . Similarly if META.LVL_CNT = 5 then only select columns TYPE_1 , TYPE_2 , TYPE_3 , TYPE_4 , TYPE_5 .

The column aliases, ie VALUE_1 , are values which come from the corresponding column where META.ID = 1 (as in this example). ID will always be provided, so it can be used to query table META .

EDIT The column aliases which come from META table will never have a pattern as I have shown in my example, but with LVL_CNT , at runtime we will know the number of columns. I tried to @Asfakul's provided logic and built a dynamic sql using the column names retrieved dynamically but when using EXECUTE IMMEDIATE INTO I realized I don't know how many columns will be retrieved and therefore wouldn't be able to dynamically generate the alias name with this method.

Need an approach to automatically build this select statment using above information.. how can I achieve this? Please provide any examples.

You can use this as the basis

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

I recommend this approach, if you already know how to build dynamic SQL, then use this concept to build your query:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM