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

发布于 2024-10-07 23:27:29 字数 156 浏览 1 评论 0原文

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

谢谢,安德鲁

I am trying to get a winform app to refresh an embedded browser on a database change using Oracle 10g. The only problem is that I am not allowed to use Database Change Notification. I am curious if anyone has a way of using the built-in package of DBMS_Alert and have had some action happen to a winform app on a database change.

Thanks, Andrew

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙气飘飘 2024-10-14 23:27:29

深思......

如果您使用 ODP,您可以使用 Oracle 高级队列/流
以及此处

这样您的表单应用程序就可以订阅队列并收到更改通知。

然而,如果您只想将新的 PO # 添加到下拉列表中,这对您的应用程序来说可能是巨大的杀伤力!

我以前使用过流,它按预期工作,但它有很好的研究和试用水平。获取点击内容时出错。

food for thought...

if you are using ODP, you could use Oracle Advanced Queuing/Streams
and here.

this way your form app can subscribe to a queue and be notified of a change.

This may, however, be massive overkill for your application if you just want to add a new PO # into a drop down!

I have used streams before and it works as expected, but it had a nice level of research and trial & error to get things to click.

暗藏城府 2024-10-14 23:27:29

我必须这样做才能让它发挥作用。我知道它会锁定窗口,直到发生事件,但至少它可以与 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();

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

I had to do it like this for it to work. It holds the window in lock until an event occurs i know, but at least it works with DBMS_Alert. I set this code inside a timer:

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();

This gives me what I need. I don't know if there is a better way to do it, but this is the only solution I could come up with.

清引 2024-10-14 23:27:29

最好不使用定时器。下面的代码示例使用后台线程

这是代码片段

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
        }
    }
}

It is better to use without timer. The below code sample is with background thread

Here is the code snippet

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
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文