Oracle 动态SQL SELECT INTO返回可怕的ORA-00933:SQL命令未正确结束
我正在执行以下动态语句,并收到ORA-00933:SQL命令未正确结束:Oracle 动态SQL SELECT INTO返回可怕的ORA-00933:SQL命令未正确结束,oracle,plsql,dynamic-sql,execute-immediate,select-into,Oracle,Plsql,Dynamic Sql,Execute Immediate,Select Into,我正在执行以下动态语句,并收到ORA-00933:SQL命令未正确结束: FUNCTION IsValidArchive RETURN BOOLEAN IS x BOOLEAN := TRUE; isValidArc_sql VARCHAR2(2000); BEGIN isValidArc_sql := 'SELECT COUNT(*), SUM(AMOUNT) ' || 'FROM ' || srcSche
FUNCTION IsValidArchive RETURN BOOLEAN
IS
x BOOLEAN := TRUE;
isValidArc_sql VARCHAR2(2000);
BEGIN
isValidArc_sql := 'SELECT COUNT(*), SUM(AMOUNT) ' ||
'FROM ' || srcSchemaTable ||
' WHERE TRUNC( ' || parm_rec.SRC_DATE_COLUMN || ' ) < ADD_MONTHS( ' ||
'ADD_MONTHS ( TRUNC ( NVL ( TO_DATE ( :parm_rec.SYS_OFFSET ) , SYSDATE) - ( :parm_rec.DAY_OFFSET )), ' ||
'( :parm_rec.MON_OFFSET * :kNEGATIVE ) ), ' ||
'( :parm_rec.YR_OFFSET * ( :kANNUM * :kNEGATIVE ) ) ); ';
EXECUTE IMMEDIATE isValidArc_sql
INTO arc_cnt, arc_amt
USING parm_rec.SYS_OFFSET, parm_rec.DAY_OFFSET, parm_rec.MON_OFFSET, kNEGATIVE, parm_rec.YR_OFFSET, kANNUM;
IF arc_cnt > 0 AND arc_amt > 0
THEN x := TRUE;
ELSE
x := FALSE;
END IF;
DBMS_OUTPUT.PUT_LINE( 'IsValidArchive: ' || CHR(10) ||
'Record Count - ' || arc_cnt || CHR(10) ||
'Total Amount - ' || arc_amt || CHR(13) );
RETURN x;
END IsValidArchive;
函数IsValidArchive返回布尔值
是
x布尔值:=真;
isValidArc_sql VARCHAR2(2000年);
开始
isValidArc_sql:=“选择计数(*),总和(金额)”||
“FROM”| | srcSchemaTable||
其中TRUNC(“| | parm_rec.SRC_DATE_COLUMN | |”)0且弧长>0
那么x:=真;
其他的
x:=假;
如果结束;
DBMS|u输出.PUT_行('IsValidArchive:'|| CHR(10)||
“记录计数-”||弧|cnt|CHR(10)||
“总金额-”| |弧| | | | CHR(13));
返回x;
结束语为有效达奇夫语;
如果我删除WHERE子句,这段代码将执行,这使我相信这可能是一个绑定变量问题。话虽如此,我在程序的另一部分中使用了相同的WHERE子句(这里减去一个bind变量),没有错误
我的绑定变量都填充了适当的值,语句中的文字看起来也正确
我的研究表明这种语法是正确的。我觉得问题出在哪里,很可能是绑定变量,但解决方案还没有显现出来。此代码在executeimmediate语句中出错
如果有人能指出我在这里做错了什么,我将不胜感激
谢谢
更新
感谢Kris和Alex指出我代码中的缺陷,下面是更正后的代码:
FUNCTION IsValidArchive RETURN BOOLEAN
IS
x BOOLEAN := TRUE;
BEGIN
isValidArc_sql := 'SELECT COUNT(*), SUM(AMOUNT) ' ||
'FROM ' || srcSchemaTable ||
' WHERE TRUNC( createdate ) < ADD_MONTHS( ' ||
'ADD_MONTHS ( TRUNC ( NVL ( :SYS_OFFSET , SYSDATE ) - ( :DAY_OFFSET )), ' ||
'( :MON_OFFSET * :kNEGATIVE ) ), ' ||
'( :YR_OFFSET * ( :kANNUM * :kNEGATIVE ) ) ) ';
EXECUTE IMMEDIATE isValidArc_sql
INTO arc_cnt, arc_amt
USING parm_rec.SYS_OFFSET, parm_rec.DAY_OFFSET, parm_rec.MON_OFFSET, kNEGATIVE, parm_rec.YR_OFFSET, kANNUM, kNEGATIVE;
IF arc_cnt > 0 AND arc_amt > 0
THEN x := TRUE;
ELSE
x := FALSE;
END IF;
DBMS_OUTPUT.PUT_LINE( 'IsValidArchive: ' || CHR(10) ||
'Record Count - ' || arc_cnt || CHR(10) ||
'Total Amount - ' || arc_amt || CHR(13) );
RETURN x;
END IsValidArchive;
函数IsValidArchive返回布尔值
是
x布尔值:=真;
开始
isValidArc_sql:=“选择计数(*),总和(金额)”||
“FROM”| | srcSchemaTable||
'其中TRUNC(createdate)<添加月份('||
'添加月份(TRUNC(NVL(:系统偏移,系统日期)-(:天偏移)),'||
“(:MON_OFFSET*:kNEGATIVE)),”||
“(:YR_OFFSET*(:kANNUM*:kNEGATIVE))”;
执行即时isValidArc_sql
分为弧长、弧长和弧长
使用parm_rec.SYS_OFFSET、parm_rec.DAY_OFFSET、parm_rec.MON_OFFSET、kNEGATIVE、parm_rec.YR_OFFSET、kANNUM、kNEGATIVE;
如果弧长>0且弧长>0
那么x:=真;
其他的
x:=假;
如果结束;
DBMS|u输出.PUT_行('IsValidArchive:'|| CHR(10)||
“记录计数-”||弧|cnt|CHR(10)||
“总金额-”| |弧| | | | CHR(13));
返回x;
结束语为有效达奇夫语;
正如@KrisRice所指出的,动态语句中不应该有尾随分号。这是SQL*Plus等中客户机定义的语句分隔符和/或终止符,但这是不同的上下文-在动态调用中只能有一条语句,因此它没有任何意义
然后您的绑定有点不正确。您似乎认为需要使用bind变量名来匹配using
子句中的变量名,因此您可以使用:parm\u rec.SYS\u OFFSET
之类的内容。这里的bind变量名实际上只是parm\u rec
部分。请记住,生成的语句是在SQL上下文中执行的,而不是在PL/SQL上下文中执行的,因此句点被解释为schema.object.column模式的一部分,当句点之前的第一部分是变量时,这是没有意义的
:parm_rec
bind变量名与parm_rec
PL/SQL记录名无关。你本可以同样有效地使用set的:b0.SYS\u,这可能会使混淆更加清楚<代码>:b0
不是对象或参考,因此为ORA-22806
因此,将:record.field
样式的引用更改为简单标识符,它仍然可以与匹配变量有一些名义关系,例如:
isValidArc_sql := 'SELECT COUNT(*), SUM(AMOUNT) ' ||
'FROM ' || srcSchemaTable ||
' WHERE TRUNC( ' || parm_rec.SRC_DATE_COLUMN || ' ) < ADD_MONTHS( ' ||
'ADD_MONTHS ( TRUNC ( NVL ( TO_DATE ( :SYS_OFFSET ) , SYSDATE) - ( :DAY_OFFSET )), ' ||
'( :MON_OFFSET * :kNEGATIVE ) ), ' ||
'( :YR_OFFSET * ( :kANNUM * :kNEGATIVE ) ) ) ';
EXECUTE IMMEDIATE isValidArc_sql
INTO arc_cnt, arc_amt
USING parm_rec.SYS_OFFSET, parm_rec.DAY_OFFSET, parm_rec.MON_OFFSET, kNEGATIVE, parm_rec.YR_OFFSET, kANNUM, kNEGATIVE;
isValidArc\u sql:='SELECT COUNT(*),SUM(AMOUNT)'||
“FROM”| | srcSchemaTable||
其中TRUNC(“| | parm_rec.SRC_DATE_COLUMN | |”)
我还添加了缺少的bind变量,在末尾重复了kNEGATIVE
,因为它们都被引用了