需要在ORACLE中EXECUTE IMMEDIATE语句中使用的where子句中使用动态变量



ORACLE(使用SQL DEVELOPER)。我需要正确地构造EXECUTE IMMEDIATE语句。我没有"创造"私人信件。任务是为表/日期的动态列表获取每个表每个日期的行数。我有以下内容:

 DECLARE CURSOR cur_table_name IS SELECT TABLE_NAME 
 FROM ALL_TABLES WHERE TABLE_NAME IN ('table_a', 'table_b', 'table_c');
 CURSOR cur_BEGIN_DATE IS 
  select to_date('2014-09-25 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + rownum -1 AS BEGIN_DATE,  
  to_date('2014-09-26 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + rownum -1 AS END_DATE from dual 
  Connect by level <= to_date('2014-09-30 00:00:00', 'YYYY-MM-DD HH24:MI:SS') - to_date('2014-09-25 00:00:00', 'YYYY-MM-DD HH24:MI:SS') + 1;
    var_total_rows NUMBER(15);
    var_table_name VARCHAR2 (50);
    var_bgn_date DATE;
    var_end_date DATE;
    BEGIN
  OPEN cur_TABLE_NAME;
  LOOP
    FETCH cur_TABLE_NAME INTO var_table_name;
    EXIT WHEN cur_TABLE_NAME%NOTFOUND;
    --testing output 
   DBMS_OUTPUT.PUT_LINE ('Table: '|| var_table_name);
    var_total_rows :=0;        
  OPEN cur_BEGIN_DATE; 
  LOOP
    FETCH cur_BEGIN_DATE INTO var_bgn_date, var_end_date;
    EXIT WHEN cur_BEGIN_DATE%NOTFOUND;
    --TESTING OUTPUT
     DBMS_OUTPUT.PUT_LINE ('DATES ARE: ' || var_bgn_date || ', ' ||var_end_date|| ' Table IS: '||var_table_name);
  --------THIS IS THE NOT WORKING STATEMENT DUE TO VARIABLES IN THE WHERE STATEMENT:
    execute immediate 'SELECT COUNT(*) FROM '||var_table_name || ' where  DTM >= '|| var_bgn_date ||' and DTM < '||var_end_date INTO var_total_rows;
   DBMS_OUTPUT.PUT_LINE (var_table_name||' '||var_bgn_date||' '||var_end_date ||' '||var_total_rows);
END LOOP;
CLOSE cur_BEGIN_DATE;
END LOOP;
CLOSE cur_TABLE_NAME;

结束;

如果我从where语句中删除变量(只需执行"Select*from || var_table_name into var_total_rows;"),就可以了。如果where子句中有一个静态值,它会起作用(但循环使用相同的日期,我需要更改日期!)。但我无法使语法适用于where子句中的动态变量。这能做到吗?

感谢你的帮助!

您的var_bgn_datevar_end_date变量属于DATE类型,但作为未引用的字符串插入到动态语句中,其格式基于会话NLS_DATE_FORMAT值。您将得到一个生成的语句,如:

SELECT COUNT(*) FROM table_a  where  DTM >= 2014-09-25 00:00:00 and DTM < 2014-09-26 00:00:00

您可以添加转义的单引号,将其转换为有效的语句,仍然依赖于使用相同NLS设置的隐式转换:

EXECUTE immediate 'SELECT COUNT(*) FROM '||var_table_name
  || ' where  DTM >= '''|| var_bgn_date ||''' and DTM < '''||var_end_date ||''''
INTO var_total_rows;

将生成:

SELECT COUNT(*) FROM table_a where  DTM >= '2014-09-25 00:00:00' and DTM < '2014-09-26 00:00:00'

但实际上,您应该使用绑定变量来避免任何到字符串或从字符串转换:

EXECUTE immediate 'SELECT COUNT(*) FROM '||var_table_name
  || ' where  DTM >= :bgn_date and DTM < :end_date'
INTO var_total_rows
USING var_bgn_date, var_end_date;

相关内容

  • 没有找到相关文章

最新更新