有没有办法使用 DBMS_Alert 通知 Winform 应用程序数据库更改

Posted

技术标签:

【中文标题】有没有办法使用 DBMS_Alert 通知 Winform 应用程序数据库更改【英文标题】:Is there a way to use DBMS_Alert to notify a Winform application of a database change 【发布时间】:2010-12-15 18:19:42 【问题描述】:

我正在尝试让一个 winform 应用程序在使用 Oracle 10g 更改数据库时刷新嵌入式浏览器。唯一的问题是我不允许使用数据库更改通知。我很好奇是否有人可以使用 DBMS_Alert 的内置包,并且在数据库更改时对 winform 应用程序进行了一些操作。

谢谢,安德鲁

【问题讨论】:

为什么不允许使用数据库更改通知?它正是针对这种类型的要求而制定的:“数据库更改通知是一项功能,它使客户端应用程序能够向数据库注册查询并接收通知,以响应与查询关联的对象的 DML 或 DDL 更改。” 【参考方案1】:

深思……

如果你使用 ODP,你可以使用Oracle Advanced Queuing/Streams 和here。

通过这种方式,您的表单应用可以订阅队列并收到更改通知。

但是,如果您只是想将新的 PO # 添加到下拉列表中,这对您的应用程序来说可能是大材小用!

我以前使用过流,它按预期工作,但它有很好的研究和反复试验,才能让点击的东西。

【讨论】:

【参考方案2】:

我必须这样做才能让它工作。它使窗口保持锁定状态,直到发生我知道的事件,但至少它可以与 DBMS_Alert 一起使用。我在计时器内设置了这段代码:

OracleConnection conn = new OracleConnection(ConnectionString);
conn.Open();
OracleCommand cmd = new OracleCommand("DECLARE\n" + 
                                        "MESSAGE VARCHAR2(1800) := null;\n" +
                                      "STATUS INTEGER;\n" +
                                      "BEGIN\n" +
                                        "DBMS_ALERT.REGISTER('ALERT');\n" +
                                        "DBMS_ALERT.WAITONE('ALERT', MESSAGE, STATUS);\n" + 
                                        "DBMS_ALERT.REMOVE('ALERT');\n" + 
                                      "END;", conn);

cmd.ExecuteNonQuery();
wbMain.Refresh();
conn.Dispose();

这给了我我需要的东西。我不知道是否有更好的方法,但这是我能想到的唯一解决方案。

【讨论】:

【参考方案3】:

最好不用定时器。以下代码示例带有后台线程

这里是代码sn-p

privateThread DBMSAlertThread;

private void DBMSAlert(bool Register)
        
            try
            
                string sSql;
                if (Register)
                   sSql = "call dbms_alert.register('XYZ')";
                else
                   sSql = "call dbms_alert.remove('XYZ')";
                dbmsAlert = new OracleCommand();
                dbmsAlert.CommandText = sSql;
                dbmsAlert.ExecuteNonQuery();  

                if (Register) //start the background thread
               
                   DBMSAlertThread = new Thread(AlertEvent);
                   DBMSAlertThread.IsBackground = true;
                   DBMSAlertThread.Start();
               
            
            catch (Exception LclExp)
            
                //Show error or capture in eventlog
                        
        

private void AlertEvent(object sender) 

    while (true)
    
        string Message = "";
        int Status = -1;
        bool bStatus;
        OracleParameter param;
        try
        
            OracleCommand dbmsAlert = new OracleCommand();
            dbmsAlertScan.SQL.Add("call dbms_alert.WaitOne('XYZ', :Message, :Status, 0)"); //Last parameter indicate wait time
            param = new OracleParameter("Message", OracleDbType.Varchar2, ParameterDirection.Output);
            dbmsAlert.Parameters.Add(param); 
            param = new OracleParameter("Status", OracleDbType.Varchar2, ParameterDirection.Output);
            dbmsAlert.Parameters.Add(param); 
            OracleParameter.ExceuteNonQuery();

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

            if (Status == 0) //0 = Alert Received, 1 = Timed out
            
                //notify or do ur stuff
            
        
        catch (Exception Exp)
        
            //raise an error
        
    

【讨论】:

以上是关于有没有办法使用 DBMS_Alert 通知 Winform 应用程序数据库更改的主要内容,如果未能解决你的问题,请参考以下文章

使用系统包DBMS_ALERT监视表

如何在win 8中显示吐司通知或弹出通知?

WIN10怎么关闭火狐的更新提示?

将数据从 PLSQL 程序推送到 Java 应用程序

有没有办法在新通知到达时删除已发送的通知?

有没有办法在不使用通知服务扩展的情况下将图像附加到推送通知?