首页 > 解决方案 > 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
              , 0
              , OCI_NTV_SYNTAX
              , OCI_DEFAULT))
              ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);
    ...
    ...
    if (OCIStmtExecute(connectionHandle
              , statementHandle
              , errorHandle
              , 0
              , 0
              , 0, 0, OCI_PARSE_ONLY))
              ThrowLastError(__FUNCTIONW__, __FILE__, __LINE__);

在这个特定的测试中 - OCIStmtExecute 应该失败 - 但是在调用 OCIStmtExecute 时会返回 OCI_SUCCESS(又名 0)。我应该为这些陈述使用其他标志还是应该寻找另一种方法?

我尝试在查询前加上 EXPLAIN PLAN FOR 并使用默认标志调用 OCIStmtExecute - 但这只会导致缺少关键字错误。

标签: c++plsqloracle19c

解决方案


这不是 OCI 中的错误,返回代码 OCI_SUCCESS(又名 0)是正确的。它将您的声明发送到数据库。

您的语句是一个匿名块,由 BEGIN 指示,并且包含错​​误。你可以做你想做的事,但你必须定义你选择的变量。您还没有这样做,所以这将是 1 个错误。此外,INTO 子句位于 FROM 之前,因此语句应该是“select...INTO...from”,这将是错误 2。最后,如果您选择的列是真的,那么实际上不会生成“编译" 时间错误,那将是错误 3。另外我相信 EXPLAIN PLAN 的匿名块也是无效的,但我已经很久没有遇到它了。
但是您可以尝试以下操作:声明 ThisVariableDoesntExist varchar2(50), -- 或正确的数据类型开始 select columnthatdoesntexist into thisvariabledoesntexist from derpytable whereyeahright = :bindname; 结尾;

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

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

Oracle 对象名称不区分大小写,Oracle 的回显将被折叠为大写,因此它避免使用 CamelCase,而是使用蛇形大小写。


推荐阅读