无法为C#应用程序检索DBMS_ALERT

时间:2014-06-17 21:02:49

标签: c# multithreading oracle stored-procedures

我正在尝试使用DBMS_ALERT从Oracle 11g数据库向C#应用程序提供反馈。在测试oracle工具TOAD中的存储过程时,我无法检索任何警报。

我将展示我编写的存储过程。

我这样做的原因是为winform上的进度条提供反馈。

我误用了DBMS_ALERT吗?我是Oracle新手,我的背景是MSSQL服务器。

这是我生成警报的存储过程:

CREATE OR REPLACE PROCEDURE HOWMET.DB_ALERT  (iMsg VARCHAR2) AS
PRAGMA AUTONOMOUS_TRANSACTION;
  BEGIN
    DBMS_ALERT.SIGNAL('ALERT', iMsg);
    COMMIT;
  END DB_ALERT;

这是我读取警报的存储过程:

CREATE OR REPLACE PROCEDURE HOWMET.GET_DB_ALERT_MSG(oMsg    OUT VARCHAR2,
                                                oStatus OUT INTEGER)
AS
  BEGIN
    DBMS_ALERT.REGISTER('ALERT');
    DBMS_ALERT.WAITONE('ALERT', oMsg, oStatus,5);
    DBMS_ALERT.REMOVE('ALERT');
END;

以下是我用来测试DBMS_ALERT的使用的主要存储过程:

CREATE OR REPLACE PROCEDURE HOWMET.GETDATAWITHALERTS(EmployeeCur           OUT SYS_REFCURSOR,
                                                 EmployeeGridFormatCur OUT SYS_REFCURSOR)
AS
BEGIN

DB_ALERT('Starting Point 1');  <- calling an external sproc to signal the alert
DBMS_LOCK.SLEEP(5);  

OPEN EmployeeCur FOR
SELECT EMPLOYEE_ID,
       FIRST_NAME,
       LAST_NAME,
       EMAIL,
       HIRE_DATE,
       DEPARTMENT_ID,
       CAST(SALARY AS INT) AS "SALARY"
  FROM HR.EMPLOYEES;

DB_ALERT('Mid Point 2'); <- calling an external sproc to signal the alert
DBMS_LOCK.SLEEP(5);

OPEN EmployeeGridFormatCur FOR
SELECT 'Employee ID|Hidden' AS "Employee_ID",
       'First Name' AS "First_Name",
       'Last Name|Width:90' AS "Last_Name",
       'Email|Width:80' AS "Email",
       'Hire Date|Width:80' AS "Hire_Date",
       'Dept Id|Width:65' AS "DEPARTMENT_ID",
       'Salary|Right|Fill|FMT:#`##0.00' AS "Salary"
  FROM DUAL;

DB_ALERT('End 3'); <- calling an external sproc to signal the alert
DBMS_LOCK.SLEEP(5);

END GETDATAWITHALERTS;

这是我遇到错误的C#代码。我一直收到错误 - &gt; &#34; PL / SQL:数字或值错误&#34;。

string Message = "";
int Status = -1;
bool bStatus;
try
{
  using (OracleConnection oCnn = new OracleConnection(_connectionString))
  using (OracleDataAdapter oDataAdapter = new OracleDataAdapter())
  using (OracleCommand dbmsAlert = new OracleCommand("GET_DB_ALERT_MSG", oCnn))
  {
     dbmsAlert.CommandType = CommandType.StoredProcedure;
            // create output parameters
     dbmsAlert.Parameters.Add("oMsg", OracleDbType.Varchar2, 1800, ParameterDirection.Output);
     dbmsAlert.Parameters.Add("oStatus", OracleDbType.Int32, ParameterDirection.Output);
     dbmsAlert.Connection.Open();
     dbmsAlert.ExecuteNonQuery();

     bStatus = int.TryParse(dbmsAlert.Parameters["oStatus"].Value.ToString(), out Status);
     Message = dbmsAlert.Parameters["oMsg"].Value.ToString();

     if (Status == 0)  //0 = Alert Received, 1 = Timed out
     {
        if (Message != null && Message != String.Empty && Message != "null")
        {
           MessageBox.Show(Message, "Feedback");
        }
        else
        {
           MessageBox.Show(System.String.Format("No Message! Status:{0} Msg:{1}", Status, Message), "Feedback");
        }
     }
  }
}
catch
{
  throw;
  //raise an error
}

1 个答案:

答案 0 :(得分:0)

我发现了这个问题。它与我在Oracle.DataAccess.Client命名空间中使用OracleParameterCollection的add方法有关。我使用此方法的较少参数导致实现错误的覆盖。在我的原始帖子中,我有以下行来指定检索dbms警报的存储过程的输出参数。

dbmsAlert.Parameters.Add("oMsg", OracleDbType.Varchar2, 1800, ParameterDirection.Output);

这是使用以下覆盖:

public OracleParameter Add(string name, OracleDbType dbType, int size, 
string srcColumn);

我应该写这个:

dbmsAlert.Parameters.Add("oMsg", OracleDbType.Varchar2, 1800, Message, ParameterDirection.Output);

这是使用所需的覆盖:

public OracleParameter Add(string name, OracleDbType dbType, int size, 
object val, ParameterDirection dir;

我的C#应用​​程序现在可以从Oracle检测DBMS_ALERT。