c++ - 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 - 但这只会导致缺少关键字错误。
解决方案
这不是 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,而是使用蛇形大小写。
推荐阅读
- css - 如何在框中设置动态边距
- sql - ORACLE CONNECT BY LEVEL 产生重复行并产生性能问题
- python - 关于如何使用面向对象编程来简化程序的任何想法
- regex - 使用多行正则表达式获取 grep 上下文
- python - 匹配python中2组列表中最相似的列表
- linux - 如何将 jar 文件从位于 myfolder/folderName 的文件夹中复制到 Fedora Linux 中的 urs/lib/jvm/java-1.8/jre/lib/etc?
- python - 使用 scipy 将阻尼正弦波拟合到数据中
- java - 仅提取十进制值以将 .Miles 转换为 Yards
- javascript - 以不同用户身份登录后如何更改 Redux 持久化数据
- c++ - C++ 使用不同方法的签名覆盖理解