由于 ORA-00920 导致过程失败:无效的关系运算符
Posted
技术标签:
【中文标题】由于 ORA-00920 导致过程失败:无效的关系运算符【英文标题】:Procedure failed due to ORA-00920: invalid relational operator 【发布时间】:2015-11-13 07:23:44 【问题描述】:在 12c oracle 中执行时出现以下错误,但在 oracle 10.2.0.4 中运行正常:
由于 ORA-00920 导致过程 proc_up_dts_product_cat_dynsql 失败:无效 关系运算符 这是程序:
CREATE OR REPLACE PROCEDURE SEAPROB.proc_up_dts_product_cat_dynsql(tablename IN varchar)
AS
dynamicsql varchar(8000);
ID int;
DTS_Segment_op varchar2(10);
DTS_Segment varchar2(15);
DTS_Segment_where varchar2(255);
DateEntered_op varchar2(10);
DateEntered varchar2(30);
DateEntered_where varchar2(255);
Svc_Name_op varchar2(10);
Svc_Name varchar2(100);
Svc_Name_where varchar2(255);
Product_Category varchar2(75);
Priority int;
combined_status_where varchar2(255);
refdate date ;
CURSOR PrivCursor
IS
SELECT
ID,
DTS_Segment_op,
Nvl(upper(trim(DTS_Segment)),' '),
DateEntered_op,
CASE WHEN dateentered='%' THEN dateentered
WHEN dateentered LIKE '%/%/____' THEN To_Char(To_Date(dateentered,'MM/DD/YYYY'),'YYYY-MM-DD')
WHEN dateentered LIKE '%/%/__' THEN To_Char(To_Date(dateentered,'MM/DD/YY'),'YYYY-MM-DD')
WHEN dateentered LIKE '''%/%/%'' % ''%/%/%''' THEN ''''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,1)+1,InStr(dateentered,'''',1,2)-InStr(dateentered,'''',1,1)-1),'MM/DD/YY'),'YYYY-MM-DD')||''' and '''||To_Char(To_Date(SubStr(dateentered,InStr(dateentered,'''',1,3)+1,InStr(dateentered,'''',1,4)-InStr(dateentered,'''',1,3)-1),'MM/DD/YY'),'YYYY-MM-DD')||''''
ELSE dateentered END AS dateentered,
Svc_Name_op,
Nvl(upper(trim(Svc_Name)),' '),
Product_Category,
Priority
FROM tbl_dts_pt_lookup order by priority desc;
BEGIN
refdate := ADD_MONTHS(to_date(SYSDATE,'dd-mon-yy'),-6) ;
OPEN PrivCursor;
-- Loop through all the rows in the tbl_dts_category_lookup table
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
WHILE PrivCursor%found
LOOP
-- Create dynamic SQL
--define case statements for where clause components
combined_status_where := ' where (DTS_Cm_DisputeStatus <>'|| '''C''' || ' OR ( DTS_Cm_DisputeStatus='|| '''C''' || ' AND DTS_CM_CLOSEDATE >= '''||refdate||'''))' ;
dts_segment_where := case when dts_segment='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(segment),chr(0),''' || ''')),''' || ' '') ' || dts_segment_op || ' ''' || dts_segment || '''' end;
svc_name_where := case when svc_name='%' then ' and 1=1' else ' and NVL(trim(Replace(Upper(dts_cm_servicename),chr(0),''' || ''')),''' || ' '') ' || svc_name_op || ' ''' || svc_name || '''' end ;
dateentered_where := case when dateentered='%' then ' and 1=1'
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
else ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') ' || dateentered_op || ' ''' || dateentered || '''' end ;
dynamicsql := 'update '||tablename||' set product_cat_id=' || cast(id as varchar) ||', product_category =''' || product_category || '''';
--add where clause
dynamicsql := dynamicsql || combined_status_where || dts_segment_where || dateentered_where || svc_name_where;
EXECUTE IMMEDIATE dynamicsql;
COMMIT;
FETCH PrivCursor
INTO
ID,
DTS_Segment_op,
DTS_Segment,
DateEntered_op,
DateEntered,
Svc_Name_op,
Svc_Name,
Product_Category,
Priority;
END LOOP;
CLOSE PrivCursor;
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Procedure proc_up_dts_product_cat_dynsql failed due to '||SQLERRM);
END proc_up_dts_product_cat_dynsql;
/
【问题讨论】:
EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE
首先,从您的代码中删除此错误。然后使用SHOW ERRORS
获取具有确切行号的完整错误堆栈。如果是运行时错误,则复制粘贴您的 SQL*Plus 会话并编辑您的问题以添加详细信息。
@LalitKumarB 为什么认为EXCEPTION WHEN OTHERS THEN
.. 是一个错误?
@Moudiz 只需谷歌WHEN OTHERS Oracle bug
。否则,请阅读我的文章,WHEN OTHERS – A bug 其他一些有用的文章 orafaq.com/wiki/WHEN_OTHERS 和 Thomas Kyte 的这篇 tkyte.blogspot.in/2012/05/pokemon-and-when-others.html 以及 asktom.oracle.com/pls/apex/… 底线“当其他人几乎总是BUG,除非紧跟在 RAISE 之后。"
@Bhuvananagulan 您能否评论EXECUTE IMMEDIATE
语句并在其前面添加DBMS_OUTPUT.PUT_LINE(dynamicsql);
并在SQL*Plus 中重新执行。请确保在执行该过程之前执行set serveroutput on
。
尝试在没有 DBMS_OUTPUT 的情况下执行在下面的行中出现错误:dynamicsql := 'update '||tablename||'设置 product_cat_id=' || cast(id as varchar) ||', product_category =''' ||产品类别 || ''''; --add where 子句 dynamicsql := dynamicsql ||组合状态位置 || dts_segment_where || dateentered_where || svc_name_where;
【参考方案1】:
当我们在 WHERE 子句中提交带有语法错误的 SQL 语句时,数据库会抛出 ORA-00920: invalid relational operator
。通常这是一个错字。这在动态 SQL 中非常容易做到,因为除了运行时我们无法看到整个语句。
您尚未发布生成的更新声明。好吧,您不能,因为您的异常处理不会显示它。专业提示:使用动态 SQL 时始终记录或显示生成的语句,如果无处可在异常块中:
dbms_output.put_line('generated statement:'|| dynamicsql);
所以这只是一个猜测,但这条线看起来很可疑......
when dateentered_op='between' then ' and TO_CHAR(dts_cm_dateentered,''YYYY-MM-DD'') between ' || dateentered
... 因为它似乎生成了一个没有 AND 子句的 BETWEEN 语句。 BETWEEN 运算符需要两个界限。
但这可能是很多事情。您可能正在使用不寻常的参数组合运行,这会生成无效的语句。您需要更好的日志记录。
【讨论】:
以上是关于由于 ORA-00920 导致过程失败:无效的关系运算符的主要内容,如果未能解决你的问题,请参考以下文章
在Oracle Apex中显示按钮时,服务器端条件取决于页面项的值?
由于安全组悬空而导致 Elastic Beanstalk 部署失败