简体   繁体   中英

PL/SQL Extract Column Names and use in select statement

ADB Table

亚行表

Todays Date

今天的日期

I have a ADB table. I want to extract the Column name base on system date

I'm currently trying the following which is not working.

SELECT (
        SELECT DISTINCT TO_CHAR(TODAY, 'MON') || '_' || TO_CHAR(TODAY, 'D') AS TODAY
        FROM STTM_DATES
        )
FROM adb

I'm trying this script but no result set.

SQLSTMT VARCHAR2(2000); 
SQLSTMT := 'SELECT' || ' ' || (SELECT DISTINCT TO_CHAR(TODAY,'MON') || '_' || TO_CHAR(TODAY,'D')AS TODAY FROM STTM_DATES)||' ' || 'FROM ADB'; 
EXECUTE IMMEDIATE SQLSTMT; 

If you are getting just a single row, you need a target to store that result (and an INTO expression), eg

SQL> create table t ( a1 int, a2 int, a3 int );

Table created.

SQL>
SQL> insert into t values (1,2,3);

1 row created.

SQL>
SQL> set serverout on
SQL> declare
  2    col_name varchar2(30);
  3    result int;
  4  begin
  5    col_name := 'a1';
  6    execute immediate 'select '||col_name||' from t' into result;
  7    dbms_output.put_line(result);
  8
  9    col_name := 'a2';
 10    execute immediate 'select '||col_name||' from t' into result;
 11    dbms_output.put_line(result);
 12  end;
 13  /
1
2

PL/SQL procedure successfully completed.

If you are receiving a set of rows, you would need to cycle through a cursor.

SQL>
SQL> insert into t values (4,5,6);

1 row created.

SQL>
SQL>
SQL> set serverout on
SQL> declare
  2    col_name varchar2(30) := 'a3';
  3    result int;
  4    rc sys_refcursor;
  5  begin
  6    open rc for 'select '||col_name||' from t';
  7    loop
  8      fetch rc into result;
  9      exit when rc%notfound;
 10      dbms_output.put_line(result);
 11    end loop;
 12    close rc;
 13  end;
 14  /
3
6

PL/SQL procedure successfully completed.

SQL>
SQL>

But neither of these fix the concerns others have expressed about the potential design issues here.

CREATE TABLE CUSTDET(CUSTACNO NUMBER, DT DATE, VAL NUMBER);
INSERT INTO CUSTDET VALUES(1, SYSDATE-2, 10);
INSERT INTO CUSTDET VALUES(1, SYSDATE-1, 20);
INSERT INTO CUSTDET VALUES(1, SYSDATE, 30);
INSERT INTO CUSTDET VALUES(2, SYSDATE-2, 40);
INSERT INTO CUSTDET VALUES(3, SYSDATE-1, 10);
INSERT INTO CUSTDET VALUES(3, SYSDATE, 20);
COMMIT;

You don't need a dynamic sql for this.

SELECT TO_CHAR(dt,'MON')||'_'||TO_CHAR(dt,'D') AS today FROM custdet;

Output:

TODAY
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3

If you want to use a dynamic sql you need to receive the output in a variable or table variable to display it separately.

DECLARE
    SQLSTMT VARCHAR2(2000); 
    TYPE MYTABTYP IS TABLE OF VARCHAR2(10);
    MYTABVAR MYTABTYP := MYTABTYP();
BEGIN
    SQLSTMT := q'[SELECT TO_CHAR(dt,'MON')||'_'||TO_CHAR(dt,'D') AS today FROM custdet]';
    EXECUTE IMMEDIATE SQLSTMT BULK COLLECT INTO MYTABVAR;
    FOR idx IN MYTABVAR.FIRST..MYTABVAR.LAST
    LOOP
        DBMS_OUTPUT.PUT_LINE(MYTABVAR(idx));
    END LOOP;
END;

Output:

MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3

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