如何解决 ORA-00933:SQL 命令未在 oracle 中正确结束?

Posted

技术标签:

【中文标题】如何解决 ORA-00933:SQL 命令未在 oracle 中正确结束?【英文标题】:How to resolve ORA-00933: SQL command not properly ended in oracle? 【发布时间】:2015-11-03 10:52:32 【问题描述】:

这是通过向函数传递 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;
/

【问题讨论】:

请您更新您的问题以显示 Getcampaignoutgoingemailqty 的代码(将在包正文中)。 运行您的代码时没有出现该错误。我得到零,因为你在包函数中挤压的异常 - 永远不要像那样使用when others,你不知道出了什么问题 - 这是因为日期处理。 我看不出使用这么差的异常处理程序有什么意义。 【参考方案1】:

我不知道这是否是您看到的错误的原因,但函数代码存在问题 - 如果您查看执行立即数,您就会发现

'<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;

【讨论】:

当你说#Date From#时,你的意思是作为一个参数吗?什么会调用这个函数?一些前端代码(例如 C#、Java 等)或用户手动运行它?如果是后者,他们将在哪里运行它?作为脚本还是作为图形用户界面(如 Toad)中的临时语句?【参考方案2】:

您在动态 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;

【讨论】:

【参考方案3】:
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

【讨论】:

复制查询时遗漏的相同问题

以上是关于如何解决 ORA-00933:SQL 命令未在 oracle 中正确结束?的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00933: SQL 命令未在存储过程中正确结束

ORACLE:错误错误(6,3):PL/SQL:SQL 语句被忽略和错误(8,3):PL/SQL:ORA-00933:SQL 命令未在过程中正确结束

oracle 问题 ORA-00933: SQL 命令未正确结束 如何解决?

oracle 问题 ORA-00933: SQL 命令未正确结束 如何解决?

如何使用另一个表中的另一列更新一列? SQL 错误:ORA-00933:SQL 命令未正确结束

ora-00933: sql 命令未正确结束怎么解决