Как решить ORA-00933: команда SQL неправильно завершена в Oracle?
Вот пакет, созданный путем передачи 3 входных параметров в функцию
CREATE OR replace PACKAGE "PKG_CAMPAIGN_EMAIL_QTY"
AS
FUNCTION Getcampaignoutgoingemailqty(
tablename IN VARCHAR2,
ActivatedDate IN DATE,
CompletedDate IN DATE)
RETURN NUMBER;
END pkg_campaign_email_qty;
/
Вот запрос, чтобы получить количество
SELECT
(
pkg_campaign_email_qty.Getcampaignoutgoingemailqty(
9142632263013677974,
To_date('20/10/2015', 'DD/MM/YYYY'),
To_date('30/11/2015', 'DD/MM/YYYY')
)
) AS
email
FROM dual;
Получение ORA-00933: команда SQL неправильно завершена в Oracle
вот тело пакета
CREATE OR REPLACE PACKAGE BODY "PKG_CAMPAIGN_EMAIL_QTY" as
FUNCTION getCampaignOutgoingEmailQty(tableName IN VARCHAR2 ,ActivatedDate DATE,CompletedDate DATE) RETURN NUMBER IS
OutgoingEmailQuantity NUMBER;
begin
EXECUTE IMMEDIATE 'select NVL(COUNT(1),0) from campaign_'||tableName||'
join flat_interactions out_email on campaign_'||tableName||'.fullname=out_email.o_parent_id and out_email.N9135700037713613964=9135706250013621563 and out_email.D9135699928113613119 between TO_DATE(''ActivatedDate'',''MM/dd/YYYY'') and TO_DATE(''CompletedDate'',''MM/dd/YYYY'')' INTO OutgoingEmailQuantity;
RETURN OutgoingEmailQuantity ;
EXCEPTION
WHEN OTHERS THEN
RETURN 0;
end getCampaignOutgoingEmailQty;
end PKG_CAMPAIGN_EMAIL_QTY;
/
3 ответа
Я не знаю, является ли это причиной ошибки, которую вы видите, но есть проблема с кодом функции - если вы загляните внутрь выполнения немедленно, вы получите
'<snip> and out_email.D9135699928113613119 between TO_DATE(''ActivatedDate'',''MM/dd/YYYY'') and TO_DATE(''CompletedDate'',''MM/dd/YYYY'')'
Это означает, что, передав эти параметры, вы в конечном итоге попытаетесь выполнить инструкцию sql:
select NVL(COUNT(1),0)
from campaign_9142632263013677974
join flat_interactions out_email on campaign_9142632263013677974.fullname = out_email.o_parent_id
and out_email.N9135700037713613964 = 9135706250013621563
and out_email.D9135699928113613119 between TO_DATE('ActivatedDate','MM/dd/YYYY')
and TO_DATE('CompletedDate','MM/dd/YYYY');
Итак, вы пытаетесь преобразовать строки "ActivatedDate" и "CompletedDate" в даты, когда они явно не являются датами.
Вместо этого я бы использовал переменные связывания, что-то вроде:
create or replace package body pkg_campaign_email_qty
as
function getcampaignoutgoingemailqty(tablename in varchar2 ,activateddate date,completeddate date)
return number
is
outgoingemailquantity number;
begin
execute immediate 'select NVL(COUNT(1),0)'||chr(10)||
'from campaign_'||tablename||chr(10)||
' join flat_interactions out_email on campaign_'||tablename||'.fullname=out_email.o_parent_id'||chr(10)||
' and out_email.N9135700037713613964=9135706250013621563'||chr(10)||
' and out_email.D9135699928113613119 between :ActivatedDate and :CompletedDate' into outgoingemailquantity using activateddate, completeddate;
return outgoingemailquantity;
exception
when others then
return 0;
end getcampaignoutgoingemailqty;
end pkg_campaign_email_qty;
/
Примечание: не проверено, поскольку вы не предоставили никаких определений таблиц.
Кроме того, в вашем вызывающем запросе внешние скобки не нужны, и я бы удалил их, поэтому ваш запрос станет:
SELECT pkg_campaign_email_qty.Getcampaignoutgoingemailqty(9142632263013677974,
To_date('20/10/2015', 'DD/MM/YYYY'),
To_date('30/11/2015', 'DD/MM/YYYY')) email
FROM dual;
Вы неправильно используете даты в динамическом sql.
Я буду использовать связки для этого:
EXECUTE IMMEDIATE
'select NVL(COUNT(1),0)
from campaign_'||tableName||'
join flat_interactions out_email on
campaign_'||tableName||'.fullname=out_email.o_parent_id and
out_email.N9135700037713613964=9135706250013621563 and
out_email.D9135699928113613119 between :ActivatedDate and :CompletedDate'
INTO OutgoingEmailQuantity
USING ActivatedDate, CompletedDate;
То, что вы хотите сделать, сложнее следовать:
EXECUTE IMMEDIATE
'select NVL(COUNT(1),0)
from campaign_'||tableName||'
join flat_interactions out_email on
campaign_'||tableName||'.fullname=out_email.o_parent_id and
out_email.N9135700037713613964=9135706250013621563 and
out_email.D9135699928113613119 between
TO_DATE('||to_char(ActivatedDate,'MM/dd/YYYY')||',''MM/dd/YYYY'')
and
TO_DATE('||to_char(CompletedDate,'MM/dd/YYYY')||',''MM/dd/YYYY'')'
INTO OutgoingEmailQuantity;
SELECT
(
pkg_campaign_email_qty.Getcampaignoutgoingemailqty(9142632263013677974, To_date('20/10/2015', 'DD/MM/YYYY'), To_date('30/11/2015', 'DD/MM/YYYY')) ) AS
email
FROM dual
); <- missing