gpt4 book ai didi

c++ - OCIErrorGet 和 OCI_ERROR 的多重错误处理

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:27:45 27 4
gpt4 key购买 nike

对于 OCIErrorGet(),据记载它可能会返回多个错误,我使用以下方法为 OCI_SUCCESS_WITH_INFO 提取这些错误,但目前对 没有OCI_ERROR:

void check_error( sword status )
{
switch( status ) {
case OCI_SUCCESS:
break;

case OCI_SUCCESS_WITH_INFO:
{
ub4 recordno = 1;
while( status != OCI_NO_DATA ) {
sb4 errcode = 0;
text errbuf[ 1024 ];
status = ::OCIErrorGet( m_err, recordno, (text*)NULL, &errcode, errbuf, sizeof( errbuf ), OCI_HTYPE_ERROR );
if( status == OCI_SUCCESS ) {
std::cout << "oracle info: " << (const char*)errbuf << std::endl;
}
else {
assert( status == OCI_NO_DATA );
}
++recordno;
}
}
break;

case OCI_ERROR:
{
sb4 errcode = 0;
text errbuf[ 1024 ];
// note here: no check of returned value from OCIErrorCode(), no loop!
::OCIErrorGet( m_err, 1, (text*)NULL, &errcode, errbuf, sizeof( errbuf ), OCI_HTYPE_ERROR );
throw my_oracle_error( errcode, (const char*)errbuf );
}
break;
default:
throw "something else";
}
}

(当然真正的代码有点不同,但重要的部分在上面)。

如果出现OCI_ERROR(在上面的代码中标有注释),我的问题是:

  • 我是否需要类似的循环,或者 Oracle 是否保证/记录在这种情况下只能返回一个错误?
  • 在这种情况下,我是否需要检查 OCIErrorGet() 的返回值?
  • 如果可以返回多个错误,我应该使用哪个 errcode 作为我抛出的异常?

答案最好应该链接到 Oracle 的文档。

最佳答案

Oracle 保证每次调用 OCIErrorGet() 只会返回一个错误。 (注意单数):

Returns an error message in the buffer provided and an Oracle Database error code.
...
Multiple diagnostic records can be retrieved by calling OCIErrorGet() repeatedly until there are no more records (OCI_NO_DATA is returned). OCIErrorGet() returns at most a single diagnostic record.

您是否需要类似的循环取决于您调用的 (PL/)SQL 代码。简单的SQL语句一般只会返回一个错误码;例如:

SQL> select 1/0 from dual;
select 1/0 from dual
*
ERROR at line 1:
ORA-01476: divisor is equal to zero

但是,如果涉及 PL/SQL,则可能返回更多:

SQL> begin
2 raise_application_error(-20000, 'error');
3 end;
4 /
begin
*
ERROR at line 1:
ORA-20000: error
ORA-06512: at line 2

此处您感兴趣的实际错误是 ORA-20000。甲骨文的exception propagation从内部 block 到外部 block 工作,因此,假设您不处理编译错误,则错误的原始原因将是第一个异常。如果您确实捕获并重新引发异常,则情况会发生变化。 Oracle 在文档中给出的示例是:

SQL> begin
2 dbms_output.put_line(1/0); -- handled
3 exception when zero_divide then
4 dbms_output.put_line(1/0 || ' is undefined'); -- not handled
5 end;
6 /
begin
*
ERROR at line 1:
ORA-01476: divisor is equal to zero
ORA-06512: at line 4
ORA-01476: divisor is equal to zero

DBMS_OUTPUT.PUT_LINE 是一个过程,因此相同的异常出现了两次;请注意,它仍然是您感兴趣的第一个异常。

回答您的问题:

不需要类似的循环;如果您想获得多个错误代码,则只应使用一个。

如果返回多个错误,由于 Oracle 传播异常的方法,您可能应该抛出第一个错误代码;不过,这本质上是您需要做出的判断。从文档中不清楚 OCIErrorGet() 是先返回最近的还是最早的异常;您可能需要抛出 last 异常。

关于c++ - OCIErrorGet 和 OCI_ERROR 的多重错误处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18734554/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com