Oracle PL SQL - проблема с EXECUTE IMMEDIATE
DECLARE
start_date VARCHAR2(12);
end_date VARCHAR2(12);
start_epochtime VARCHAR2(15);
end_epochtime VARCHAR2(15);
v_sql VARCHAR2(1024);
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);
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]';
END;
/
Я получил эту ошибку ORA-01008: not all variables bound
когда я бегу этот пл. И все заявления работают нормально, кроме EXECUTE IMMEDIATE q''
;
2 ответа
Похоже, нет причин использовать EXECUTE IMMEDIATE
Вот. Вы не создаете динамический запрос и не выполняете оператор DDL. Я предлагаю заменить 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
Удачи.
Если вы действительно хотите сделать все это в PL/SQL, то вы можете сделать:
VARIABLE cur REFCURSOR;
DECLARE
start_date VARCHAR2(12);
end_date VARCHAR2(12);
start_epochtime VARCHAR2(15);
end_epochtime VARCHAR2(15);
v_sql VARCHAR2(1024);
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 value */
start_epochtime := ( DATE '2016-01-01' - DATE '1970-01-01' ) * 24 * 60 * 60 * 1000;
end_epochtime := ( 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 := ( CURRENT_DATE - DATE '1970-01-01' ) * 24 * 60 * 60 * 1000;
end_epochtime := ( CURRENT_DATE - 30 - DATE '1970-01-01' ) * 24 * 60 * 60 * 1000;
dbms_output.put_line(start_epochtime);
dbms_output.put_line(end_epochtime);
OPEN :cur FOR
select to_char(DATE '1970-01-01' + CREATIONDATE/1000/24/60/60,'YYYY-MM-DD'),
count(1)
from jivemessage_us
where CREATIONDATE BETWEEN start_epochtime and end_epochtime
group by CREATIONDATE
order by 1;
END;
/
PRINT cur;
Но было бы проще сделать это в SQL:
select to_char(DATE '1970-01-01' + CREATIONDATE/1000/24/60/60,'YYYY-MM-DD'),
count(1)
from jivemessage_us
where CREATIONDATE BETWEEN ( CURRENT_DATE - DATE '1970-01-01' )*24*60*60*1000
AND ( CURRENT_DATE - 30 - DATE '1970-01-01' )*24*60*60*1000
group by CREATIONDATE
order by 1;
(Примечание: я оставил вашу логику как есть, но перевел ее с непрерывного переключения контекста с PL/SQL на SQL, чтобы просто использовать как можно больше PL/SQL и литералы ANSI Date; однако я думаю, что у вас есть -30
в неправильных местах, как это должно быть для start_epochtime
а не end_epochtime
.)