PL/SQL提取列名并在select语句中使用

PL/SQL提取列名并在select语句中使用,sql,oracle,plsql,oracle11g,Sql,Oracle,Plsql,Oracle11g,亚洲开发银行表 今天的日期 我有一张桌子。我想根据系统日期提取列名 我目前正在尝试以下不起作用的方法 SELECT ( SELECT DISTINCT TO_CHAR(TODAY, 'MON') || '_' || TO_CHAR(TODAY, 'D') AS TODAY FROM STTM_DATES ) FROM adb 我正在尝试此脚本,但没有结果集 SQLSTMT VARCHAR2(2000); SQLSTMT := 'SELECT'

亚洲开发银行表

今天的日期

我有一张桌子。我想根据系统日期提取列名

我目前正在尝试以下不起作用的方法

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

我正在尝试此脚本,但没有结果集

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; 
对此,您不需要动态sql

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

TODAY
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3
如果要使用动态sql,则需要在变量或表变量中接收输出以单独显示

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;
输出:

TODAY
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3
MAR_1
MAR_2
MAR_3

如果只得到一行,则需要一个目标来存储该结果和一个表达式,例如

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.
如果您正在接收一组行,则需要在光标之间循环

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>

但这两种方法都不能解决其他人对此处潜在设计问题的担忧。

我认为您的表设计不是最优的。与其将每天存储在单独的列中(这不会扩展,并且会导致黑客攻击),不如将所有时间戳存储在单个列中。然后,您可以轻松地使用WHERE子句在单个列中搜索当前日期。我将使用此脚本每天更新adb,这就是我希望获得该列的原因。adb表的内容是CUST_AC_NO JAN_2 JAN_3 JAN_4 JAN_5 JAN_6 JAN_7…12月31日我的话没有人听,因为我认为您需要修复您的表设计。不要将一天存储在单独的列中,所有天都使用单个列。我正在尝试此脚本,但没有结果集。sqlstmtvarchar22000;SQLSTMT:=“选择”| |“| | |选择不同于| | |“| | |”|选择不同于| | | | | | | | | | |到| | | | | | |从ST;执行即时SQLSTMT;重要提示:请不要发布样本数据和结果集的图像。只需复制纯文本粘贴即可。你的桌子设计看起来很糟糕,你需要修复它。您正在寻找的解决方案如果得到实施,实际上可能会变得更加混乱。