拦截Microsoft Access中的Oracle raise_application_error自定义消息?

时间:2013-08-13 18:12:01

标签: oracle ms-access exception-handling error-handling adodb

摘要

我有一个带有类似EXCEPTION块的Oracle过程,如下所示。我想将raise_application_error的输出传递回Microsoft Access并将其显示给用户。它是Microsoft Access调用此Oracle过程。

EXCEPTION
  WHEN e_invalidids THEN
    raise_application_error (-20001,'Invalid ids in Upload Table.');
  WHEN e_missingdate THEN
    raise_application_error (-20002,'Missing Date in Upload Table.');
  WHEN OTHERS THEN
    raise_application_error (-20000,'An error was encountered - ' || SQLCODE || ' -ERROR- ' || SQLERRM);
END;

请求

我希望被指向正确的方向 - 给出一种在Access中报告此错误的方法。

如果解决方案是将Oracle过程转换为函数 - 那么我希望有人触及如何正确(即捕获异常然后返回值)< / p>

背景资讯

我正在编写一个userland工具,使用Access数据库作为前端将数据导入Oracle数据库。数据从Excel导入,清理,更正并针对各种验证检查进行测试。 Access然后使用ADO将数据写入Oracle服务器上的表,然后调用PL / SQL过程来处理它。

该过程执行许多验证检查(一些是重复的,一些是特定于DB的)。传递时,它会读入每条记录 - 解释它 - 并填充数据库中的规范化表。

考虑到Access中已经发生的验证检查的数量,我真的不希望从Oracle Procedure中引发任何错误 - 但是如果有,我希望将错误传递回Access并显示给用户。

我尝试了什么

我在这个论坛和Google上搜索过。从我读到的内容 - raise_application_error将输出返回给调用客户端 - 但是考虑到Oracle和Access之间存在OLE DB提供程序和ADO DB API,我猜测错误被封装并且返回了简单的Pass / Fail来自执行电话:

oraConn.Execute "import_data"
oraErrText = ""
Set oraErrors = oraConn.Errors

For Each oraError In oraErrors
  debug.print oraError.Number
  debug.print oraError.Description
  debug.print oraError.Source
  debug.print oraError.SQLState 
  debug.print oraError.NativeError
Next

以上结果只出现一个错误: ORA-00900:无效的SQL语句

1 个答案:

答案 0 :(得分:1)

在花了两周时间尝试各种各样的事情之后 - 它开始工作了。我有一种感觉,它与使用OLEDB Provider而不是ODBC驱动程序以及存储过程命令文本有关。我还将存储过程移到了包中。

Oracle设置

create or replace 
PACKAGE test AS
  PROCEDURE testSP;
END test;
/
create or replace 
PACKAGE BODY test AS
  PROCEDURE testSP IS
  BEGIN
    DECLARE
      e_test EXCEPTION;
    BEGIN
      RAISE e_test;
    EXCEPTION
      WHEN e_test THEN
        raise_application_error (-20001,'Test Error');
        RETURN;
    END;
  END;
END test;

VBA代码:

Public Sub testSP(dbCredDSN As String, dbCredUser As String, dbCredPW As String)
  Dim oraConn As ADODB.Connection
  Dim oraCmd As ADODB.Command
  Dim oraError As ADODB.Error

  Set oraConn = New ADODB.Connection

  ' Open our Connection
  Set oraConn = New ADODB.Connection
  oraConn.Mode = adModeReadWrite
  oraConn.Provider = "OraOLEDB.Oracle"
  oraConn.Properties("Data Source") = dbCredDSN
  oraConn.Properties("User ID") = dbCredUser
  oraConn.Properties("Password") = dbCredPW
  oraConn.Open

   ' Set up our Command.
  Set oraCmd = New ADODB.Command
  Set oraCmd.ActiveConnection = oraConn
  oraCmd.CommandText = "{CALL test.testSP()}"
  On Error Resume Next
  oraCmd.Execute
  On Error GoTo 0

  For Each oraError In oraConn.Errors
    Debug.Print "Number:       " & oraError.Number
    Debug.Print "Description:  " & oraError.Description
    Debug.Print "Source:       " & oraError.Source
    Debug.Print "SQL State:    " & oraError.SQLState
    Debug.Print "Native Error: " & oraError.NativeError
  Next

  ' Close the Recordset & Connection Objects
  oraConn.Close

  ' Clean Up
  Set oraConn = Nothing
  Set oraCmd = Nothing
End Sub

<强>执行:

testSP "myDSN","myUsername","myPassword"

Number:       -2147217900
Description:  ORA-20001: Test Error
ORA-06512: at "TESTSERVER.TEST", line 10
ORA-06512: at line 1
Source:       OraOLEDB
SQL State:    
Native Error: 20001