如何监视Oracle DB_中长时间运行的存储过程的执行

时间:2017-05-25 11:14:50

标签: c# oracle odp.net

我有一个存储过程正在为暂存区域准备数据以供进一步使用。此过程包含几个步骤,每个步骤持续几分钟。它是从C#前端调用的。这是简化的程序流程:

CREATE OR REPLACE PROCEDURE SP1
AS
BEGIN
  INSERT INTO T1 SELECT ... FROM T2;
  INSERT INTO P1 SELECT ... FROM P2;
  INSERT INTO Q1 SELECT ... FROM Q2;
END;

在c#代码(OracleConnection,OracleCommannd,ExecuteNonQuery ...)中调用它非常简单。 但是,由于此过程将由用户从前端执行,因此如果他/她可以监视此过程的进度,则将提供非常有用的信息。到目前为止我发现的是OracleConnection.InfoMessage事件和RAISE_APPLICATION_ERROR函数。 我正在添加

BEGIN 
  RAISE_APPLICATION_ERROR (-20001, 'My message text');
EXCEPTION
  WHEN OTHERS THEN NULL;
END;

在我的存储过程中希望InfoMessage事件将被引发而不是。这是在OracleConnection初始化期间设置的InfoMessage事件处理程序(Connection.InfoMessage + = OnInfoMessage):

private void OnInfoMessage(object sender, OracleInfoMessageEventArgs e)
{
  foreach (OracleError err in e.Errors)
  {
    ShowSomeText(err.Message);
  }
}

删除BEGIN EXCEPTION后,块错误被C#代码捕获,但在这种情况下也没有触发InfoMessage。 我在这种情况下做错了什么? 我对MsSql服务器使用了类似的技术,它运行顺畅。我是否会错过与会话/连接相关的设置?

PS

我试图避免使用可能查询某些系统对象或用户日志表的另一个连接。这将用作后备方案。

1 个答案:

答案 0 :(得分:0)

您只需创建一个序列并生成序列值即可将其保存在C#应用程序中,然后创建使用自治事务的过程,并在每次进入该步骤时调用它。

1.1

- 此过程将更新状态表中的状态

    drop sequence sq;
    create sequence s1; 

    drop table status;
    create table status(id number, descriptions varchar2(100));

- 这是您的主要程序

    CREATE OR REPLACE PROCEDURE update_status (id_in IN Number,description_in IN varchar2,dml_type_in IN varchar2) AS
      PRAGMA AUTONOMOUS_TRANSACTION;
      id_1 number:= id_in;
      description_1 varchar2(100):=description_in;
      dml_type_1 char(1):=dml_type_in;
    BEGIN
    if dml_type_1='I' then
     insert into status values(id_1, description_1);
    elsif dml_type_1 = 'U' then
     update status set descriptions=description_1 where id=id_1;
    else 
     delete from status where id=id_1;
    end if;
    commit;
    END;

如果你在网站编码,你可以使用类似ajax / jquery的东西,因为我用C#编码了

  

警告:我的错误比我做得更多,所以请按照基本要求   软件工程的原理,并始终测试代码   在生产中使用它。