我有一个存储过程正在为暂存区域准备数据以供进一步使用。此过程包含几个步骤,每个步骤持续几分钟。它是从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
我试图避免使用可能查询某些系统对象或用户日志表的另一个连接。这将用作后备方案。
答案 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#编码了
警告:我的错误比我做得更多,所以请按照基本要求 软件工程的原理,并始终测试代码 在生产中使用它。