我正在尝试使用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
}
答案 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。