在 C++ 中带有子句和函数的 oracle 的 OTL 问题

Posted

技术标签:

【中文标题】在 C++ 中带有子句和函数的 oracle 的 OTL 问题【英文标题】:OTL problem with oracle with clause and function in it in C++ 【发布时间】:2020-01-28 07:44:55 【问题描述】:

我正在使用 Oracle 18C(

SQL*Plus: Release 18.0.0.0.0 - Production on Tue Jan 28 02:44:17 2020
Version 18.8.0.0.0

) 当我尝试在 C++ 中使用 OTL 时发现了这个奇怪的问题 我有一个使用 oracle 的“with”子句的查询,如下所示:

with 
FUNCTION
SELECT QUERY with one bind variable

当我在 plsql developer 中执行这个“with cluase”查询时,它执行得很顺利。 但是当我将相同的查询放入 otl_stream 并使用绑定变量时:它会抛出一个错误:

ORA-00600: internal error code, arguments: [15216], [], [], [], [], [], [], [], [], [], [], []

出于演示目的,我创建了一些临时表并编写了一个查询:

create table test_with_func
(
int_col NUMBER(9),
varchar_col varchar2(30)
);
insert into test_with_func (INT_COL, VARCHAR_COL)
values (1, 'One');
insert into test_with_func (INT_COL, VARCHAR_COL)
values (2, 'Two');
commit;
with 
function getvalue(in_varchar in varchar2) return integer is out_int NUMBER;
begin
  select int_col
    into out_int
    from test_with_func
   where varchar_col = in_varchar;
  return out_int;
end;
select varchar_col from test_with_func where int_col = getvalue('Two')

当我把它放在 c++ 代码中时,我得到了上面提到的奇怪错误。下面是我的 C++ 代码。

#include<iostream>
#if defined(solaris32)
#define OTL_ORA9I
#else
#define OTL_ORA12C
#define OTL_UBIGINT unsigned long long
#endif //#if defined(solaris32)
#define OTL_STL // Enable STL compatibily mode
// Now we include OTL
#include <otlv4.h>

otl_connect db; // connect object
using namespace std;

int main(int argc,char **argv)

 try
  db.rlogon("user/password@dbalias"); // connect to Oracle
 

 catch(otl_exception& p) // intercept OTL exceptions
  cerr<<p.msg<<endl; // print out error message
  cerr<<p.stm_text<<endl; // print out SQL that caused the error
  cerr<<p.var_info<<endl; // print out the variable that caused the error
 

 cout<<"Connected to DB"<<endl;
   int mindom=1;
   int maxdom=9999999;
   int minrhash=1;
   int maxrhash=9999999;                                           
 string getDateQuery = " with function getvalue(in_varchar in varchar2) return integer is out_int NUMBER;     \
                         begin                                                                                \
                           select int_col                                                                     \
                             into out_int                                                                     \
                             from test_with_func                                                              \
                            where varchar_col = in_varchar;                                                   \
                           return out_int;                                                                    \
                         end;                                                                                 \
                         select varchar_col                                                                   \
                         from test_with_func                                                                  \
                         where int_col = getvalue(:inputvarchar<char[30]>)";
 string Value;
 otl_stream *getDateStream;
try
     string var="Two";
     getDateStream=new otl_stream(1, getDateQuery.c_str(), db);
     *getDateStream << var;

     while(!getDateStream->eof())
     

      *(getDateStream) >> Value;

     

   
   catch(otl_exception &p)
   
       cerr<<p.msg<<endl; // print out error message
       cerr<<p.stm_text<<endl; // print out SQL that caused the error
       cerr<<p.var_info<<endl; // print out the variable that caused the error
   

  cout<<"Value is "<<Value<<endl;
  db.logoff(); // disconnect from Oracle

return 0;

下面是输出

]$ ./a.out
Connected to DB
ORA-00600: internal error code, arguments: [15216], [], [], [], [], [], [], [], [], [], [], []

 with function getvalue(in_varchar in varchar2) return integer is out_int NUMBER;                              begin                                                                                                           select int_col                                                                                                  into out_int                                                                                                  from test_with_func                                                                                          where varchar_col = in_varchar;                                                                              return out_int;                                                                                             end;                                                                                                          select varchar_col                                                                                            from test_with_func                                                                                           where int_col = getvalue(:inputvarchar          )

Value is

这与我错过的一些预处理器宏有关吗? 有人可以在这里帮忙吗。

【问题讨论】:

【参考方案1】:

从更改查询后

with 
function getvalue(in_varchar in varchar2) return integer is out_int NUMBER;
begin
  select int_col
    into out_int
    from test_with_func
   where varchar_col = in_varchar;
  return out_int;
end;
select varchar_col from test_with_func where int_col = getvalue('Two')

with 
function getvalue(in_varchar in varchar2) return integer is out_int NUMBER;
begin
  select int_col
    into out_int
    from test_with_func
   where varchar_col = in_varchar;
  return out_int;
end;
output as(
select varchar_col from test_with_func where int_col = getvalue('Two')
)
select * from output

问题在 C++ 中使用 OTL 解决。此处的更改是将 with 子句的最后一个查询移动到子查询中,并添加了新的最终选择查询。 但请注意,这两个查询都通过 plsql developer 工作。 不知道为什么第一个查询不能通过 C++ 中的 OTL 工作。

【讨论】:

以上是关于在 C++ 中带有子句和函数的 oracle 的 OTL 问题的主要内容,如果未能解决你的问题,请参考以下文章

Oracle SQL:: 子查询中带有 orderby 的 Rownum 抛出缺少括号

在函数 Oracle PLSQL 中带最高薪水员工 id 的查询?

SQL Server 中带条件的 Where 子句

Laravel 5.8,在 where 子句中带有 Count(*) 的棘手子查询

where 子句中带有字符的整数字段返回奇怪的输出

Hive 中带有 Join 或 Where 子句的条件