Oracle 试图在变量中以历元格式获取当前_日期

Oracle 试图在变量中以历元格式获取当前_日期,oracle,plsql,Oracle,Plsql,我试图在Oracle PL/SQL变量中以历元格式获取当前日期: DECLARE start_date VARCHAR2(12); end_date VARCHAR2(12); start_epochtime VARCHAR2(15); end_epochtime VARCHAR2(15); BEGIN SELECT '''' || to_char(current_date,'YYYY-MM-DD') || '''' into start_date fr

我试图在Oracle PL/SQL变量中以历元格式获取当前日期:

DECLARE 
    start_date VARCHAR2(12);
    end_date VARCHAR2(12);
    start_epochtime VARCHAR2(15);
    end_epochtime VARCHAR2(15);
BEGIN
    SELECT '''' || to_char(current_date,'YYYY-MM-DD') || '''' into start_date from dual ;  --  '2016-01-20'
    SELECT '''' || to_char(current_date - 30,'YYYY-MM-DD') || '''' into end_date from dual ; -- '2015-12-21'
    dbms_output.put_line(start_date);
    dbms_output.put_line(end_date);
    /* Below section will convert date to epochtime with hard code date value*/
    SELECT '''' || (CAST((TO_DATE('2016-01-01','YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') ) * 24 * 60 * 60 * 1000 AS VARCHAR(15))) || '''' into start_epochtime FROM DUAL;
    SELECT '''' || (CAST((TO_DATE('2016-01-01','YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') - 30) * 24 * 60 * 60 * 1000 AS VARCHAR(15))) || '''' into end_epochtime FROM DUAL;
    dbms_output.put_line(start_epochtime);
    dbms_output.put_line(end_epochtime);
    /* Below section will convert date to epochtime with a variable and it is not working */
    SELECT '''' || (CAST((TO_DATE(start_date,'YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') ) * 24 * 60 * 60 * 1000 AS VARCHAR(15))) || '''' into start_epochtime FROM DUAL;
    SELECT '''' || (CAST((TO_DATE(end_date,'YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') - 30) * 24 * 60 * 60 * 1000 AS VARCHAR(15))) || '''' into end_epochtime FROM DUAL;
    dbms_output.put_line(start_epochtime);
    dbms_output.put_line(end_epochtime);
END;

SQL>
'2016-03-02'
'2016-02-01'
'1451606400000'
'1449014400000'
DECLARE
*
ERROR at line 1:
ORA-01841: (full) year must be between -4713 and +9999, and not be 0
ORA-06512: at line 17

问题是在变量值周围加上了单引号。字符串文字需要这些,但字符串变量不需要。它已经是一个字符串,不需要引号来表示

在你最后的转化中,你做的相当于

select TO_DATE('''2016-01-01''','YYYY-MM-DD') from dual;
得到了相同的ORA-01841

如果去掉所有额外的报价:

DECLARE 
  start_date VARCHAR2(12);
  end_date VARCHAR2(12);
  start_epochtime VARCHAR2(15);
  end_epochtime VARCHAR2(15);
BEGIN
  SELECT to_char(current_date,'YYYY-MM-DD') into start_date from dual;
  SELECT to_char(current_date - 30,'YYYY-MM-DD') into end_date from dual;
  dbms_output.put_line(start_date);
  dbms_output.put_line(end_date);
  /* Below section will convert date to epochtime with hard code date value */
  SELECT CAST((TO_DATE('2016-01-01','YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') ) * 24 * 60 * 60 * 1000 AS VARCHAR(15)) into start_epochtime FROM DUAL;
  SELECT CAST((TO_DATE('2016-01-01','YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') - 30) * 24 * 60 * 60 * 1000 AS VARCHAR(15)) into end_epochtime FROM DUAL;
  dbms_output.put_line(start_epochtime);
  dbms_output.put_line(end_epochtime);
  /* Below section will convert date to epochtime with a variable */
  SELECT CAST((TO_DATE(start_date,'YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') ) * 24 * 60 * 60 * 1000 AS VARCHAR(15)) into start_epochtime FROM DUAL;
  SELECT CAST((TO_DATE(end_date,'YYYY-MM-DD') - TO_DATE('1970-01-01','YYYY-MM-DD') - 30) * 24 * 60 * 60 * 1000 AS VARCHAR(15)) into end_epochtime FROM DUAL;
  dbms_output.put_line(start_epochtime);
  dbms_output.put_line(end_epochtime);
END;
/

PL/SQL procedure successfully completed.
2016-03-02
2016-02-01
1451606400000
1449014400000
1456876800000
1451692800000
顺便说一句,您不需要所有的上下文开关来选择dual,您可以将大多数函数的结果直接分配给PL/SQL变量:

...
BEGIN
  start_date := to_char(current_date,'YYYY-MM-DD');
  end_date := to_char(current_date - 30,'YYYY-MM-DD');
  dbms_output.put_line(start_date);
  dbms_output.put_line(end_date);
  /* Below section will convert date to epochtime with hard code date */
  start_epochtime := TO_CHAR((DATE '2016-01-01' - DATE '1970-01-01') * 24 * 60 * 60 * 1000);
  end_epochtime := TO_CHAR((DATE '2016-01-01' - DATE '1970-01-01' - 30) * 24 * 60 * 60 * 1000);
  dbms_output.put_line(start_epochtime);
  dbms_output.put_line(end_epochtime);
  /* Below section will convert date to epochtime with a variable */
  start_epochtime := TO_CHAR((TO_DATE(start_date,'YYYY-MM-DD') - DATE '1970-01-01') * 24 * 60 * 60 * 1000);
  end_epochtime := TO_CHAR((TO_DATE(end_date,'YYYY-MM-DD') - DATE '1970-01-01' - 30) * 24 * 60 * 60 * 1000);
  dbms_output.put_line(start_epochtime);
  dbms_output.put_line(end_epochtime);
END;
/
得到相同的输出


你在评论中说你正在做:

EXECUTE IMMEDIATE 
  "select to_char((TO_DATE('1970-01-01','yyyy-mm-dd') + (m.CREATIONDATE/1000/24/60/60)),'YYYY-MM-DD'),count(1) 
  from jivemessage_us m 
  where m.CREATIONDATE >= :start_epochtime 
     and m.CREATIONDATE < :end_epochtime 
  group by to_char((TO_DATE('1970-01-01','yyyy-mm-dd') + (m.CREATIONDATE/1000/24/60/60)),'YYYY-MM-DD') 
  order by 1";

或者,如果您只是计划循环查询结果,则可以将其用作查询,而不需要批量收集或收集类型。

请花时间进行查询。您使用的方法也不合适;这样会更好,也会让你的问题更具可视性。嗨,亚历克斯,谢谢你的更新。我还试图在下面的查询中使用该变量,但它会抛出一个错误。执行立即“选择至字符((至日期('1970-01-01','yyyy-mm-dd')+(至日期('1970-01-01','yyyy-mm-dd')),'yyyyy-mm-dd'),从jivemessage中计数(1),其中m.CREATIONDATE>=:开始至日期和m.CREATIONDATE<:结束至字符组((至日期('1970-01-01','yyyyy-mm-dd'),'m.CREATIONDATE/1000/24/60/60)),'yyyyyyy-mm-dd');22 23结束;24/错误:ORA-00972:标识符太小long@RajiniRajas在注释中阅读代码真的很难。但是您在动态语句周围使用了双引号(
),因此整个语句都被视为标识符,因此出现了错误。您的语句应该是字符串文字,这也意味着其中的任何单引号都需要转义,或者您可以使用替代的引号机制。
EXECUTE IMMEDIATE 
 q'[select to_char((TO_DATE('1970-01-01','yyyy-mm-dd') + (m.CREATIONDATE/1000/24/60/60)),'YYYY-MM-DD'),count(1) 
   from jivemessage_us m 
   where m.CREATIONDATE >= :start_epochtime 
       and m.CREATIONDATE < :end_epochtime 
   group by to_char((TO_DATE('1970-01-01','yyyy-mm-dd') + (m.CREATIONDATE/1000/24/60/60)),'YYYY-MM-DD') 
   order by 1]';
select trunc(DATE '1970-01-01' + (m.CREATIONDATE/1000/24/60/60)), count(*)
bulk collect into ... -- table of records
from jivemessage_us m
where m.CREATIONDATE >= start_epochtime
and m.CREATIONDATE < end_epochtime
group by TRUNC(DATE '1970-01-01' + (m.CREATIONDATE/1000/24/60/60));