Dan*_*rey 6 c++ oracle oracle-call-interface
因为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";
}
}
Run Code Online (Sandbox Code Playgroud)
(当然真正的代码有点不同,但重要部分如上所示).
如果OCI_ERROR(在上面的代码中标有注释),我的问题是:
OCIErrorGet()在这种情况下,我是否需要检查返回的值?errcode我应该将哪个错误用于我抛出的异常?答案最好应链接到Oracle的文档.
甲骨文保证只有一个错误将被返回每次通话的OCIErrorGet()(注意单数):
返回提供的缓冲区中的错误消息和Oracle数据库错误代码.
...
可以通过重复调用OCIErrorGet()来检索多个诊断记录,直到没有更多记录(返回OCI_NO_DATA).OCIErrorGet()最多返回一条诊断记录.
是否需要类似的循环或取决于您正在调用的(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
Run Code Online (Sandbox Code Playgroud)
但是,如果涉及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
Run Code Online (Sandbox Code Playgroud)
这里你感兴趣的实际错误是ORA-20000.Oracle的异常传播从内部块到外部块工作,因此,假设您没有处理编译错误,则错误的原始原因将是第一个例外.如果你捕获并重新引发异常,则会发生变化.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
Run Code Online (Sandbox Code Playgroud)
DBMS_OUTPUT.PUT_LINE是一个程序,因此出现两次同样的例外; 请注意,它仍然是您感兴趣的第一个例外.
回答你的问题:
你不需要类似的循环; 如果您想获得多个错误代码,则只应使用一个.
如果返回多个错误,您应该抛出第一个错误代码,因为Oracle传播异常的方法; 这本质上是你需要做出的判断.从文档中不清楚是否首先OCIErrorGet()返回最新或最早的例外; 你可能需要抛出最后一个异常.
| 归档时间: |
|
| 查看次数: |
1399 次 |
| 最近记录: |