我有一个存储过程,它正在为暂存区域准备数据以供进一步使用。此过程包含几个步骤,每个步骤持续几分钟。它是从 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;
在我的存储过程中,希望信息消息事件将被引发,但事实并非如此。以下是在 OracleConnection 初始化期间设置的 InfoMessage 事件处理程序(Connection.InfoMessage += OnInfoMessage):
private void OnInfoMessage(object sender, OracleInfoMessageEventArgs e)
{
foreach (OracleError err in e.Errors)
{
ShowSomeText(err.Message);
}
}
删除后,C#代码中捕获了BEGIN EXCEPTION块错误,但在这种情况下也没有触发InfoMessage。 在这种情况下,我做错了什么? 我已经对MsSql服务器使用了类似的技术,它工作顺利。我是否错过了一些与会话/连接相关的设置?
附言
我试图避免使用可能查询某些系统对象或用户日志表的另一个连接。这将用作回退方案。
只需创建一个序列并生成序列值并将其保存在 C# 应用程序中,然后创建利用自主事务的过程并在每次进入步骤时调用它即可。
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;
--这是您的主要程序
CREATE OR REPLACE PROCEDURE SP1 (id_in IN number)
AS
BEGIN
--step 1
update_status(id_in,'Entering Step 1','I');
dbms_lock.sleep(30);
--step 2
update_status(id_in,'Entering Step 2','U');
dbms_lock.sleep(30);
--step 3
update_status(id_in,'Entering Step 3','U');
dbms_lock.sleep(30);
update_status(id_in,NULL,'D');
END;
--Run procedure from 1st session
exec sp1(<whatever the sequence value is>);
--Check status from second
select * from status where id = <whatever the sequence value was>
如果你在网站中编码,你可以使用类似ajax/jquery的东西,自从我用C#编码以来已经有一段时间了
警告:我错的多于我错的,所以请遵循基本 软件工程原理,并始终在测试代码之前 在生产中使用它。