OCI 19c-解析包含SELECT-FROM-INTO语句的PL / SQL语句

问题描述

我需要使用OCI解析查询。在大多数情况下-它正在工作。但是,今天我遇到了一个我无法解决的问题。暂时-好像是OCI中的错误(当前使用19c 32位)-或由于某种原因而忽略了此类语句。

每当SQL查询包含SELECT-FROM-INTO语句时-使用OCI_PARSE_ONLY调用OCIStmtExecute时,整个查询将被忽略。查询中是否存在无效的实体名称/语法都没有关系。我试图在网上找到有关此特殊情况的其他信息-但我什么都没找到。

有问题的查询如下(该查询有意使用垃圾实体名称来说明奇怪的行为)

BEGIN
    SELECT ColumnThatDoesntExist FROM DerpyTable INTO ThisVariableDoesntExist WHERE YeahRight = :BindName;
END

下面是语句准备代码/执行代码

   ...
   ... 
   if (OCIStmtPrepare2(connectionHandle,&statementHandle,errorHandle,command,commandLength,nullptr,OCI_NTV_Syntax,OCI_DEFAULT))
              ThrowLastError(__FUNCTIONW__,__FILE__,__LINE__);
    ...
    ...
    if (OCIStmtExecute(connectionHandle,statementHandle,OCI_PARSE_ONLY))
              ThrowLastError(__FUNCTIONW__,__LINE__);

在此特定测试中-OCIStmtExecute应该失败-但是,在调用OCIStmtExecute时会返回OCI_SUCCESS(aka 0)。对于这些类型的语句,我还应该使用其他标志吗?还是应该在寻找其他方法

我尝试在查询添加EXPLAIN PLAN FOR并使用认标志调用OCIStmtExecute-但这只会导致关键字丢失错误

解决方法

这不是OCI中的错误,返回码OCI_SUCCESS(aka 0)是正确的。它已将您的语句发送到数据库。

您的声明是一个匿名阻止,由BEGIN指示,并且包含错​​误。您可以执行所需的操作,但是必须定义选择的变量。您尚未执行此操作,因此将出现1错误。同样,INTO子句位于FROM之前,因此该语句应为“ select ... INTO ... from”,这将是错误2。最后,如果为true,则您选择的列实际上不会生成“ compile”。 “时间错误,那将是错误3。另外,我相信针对匿名块的EXPLAIN PLAN也是无效的,但是距离我遇到它已经很长时间了。
但是您可以尝试以下方法: 宣布 ThisVariableDoesntExist varchar2(50),或正确的数据类型 开始 选择不算列的列 成为这个变量doesntexist 来自derpytable 其中yeahright =:bindname; 结束;

注意:作为匿名块,以上内容应运行(如果该列实际存在)。但是,您将不会获得输出。您可能希望添加

dbms_output.put_line('Value=' || ThisVariableDoesntExist);

Oracle对象名称不区分大小写,并且回显形式从Oracle折叠为大写形式,因此避免CamelCase而是使用snake_case。