执行计划 业务对象很好用,能提高效果。在这方面,最近遇到个问题,有一个客户上了云,该云环境偶尔波动,大概两周三次数据库连接不上,错误信息如下
“执行计划调用时间: ,在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。 未找到或无法访问服务器。请验证实例名称是否正确并且 SQL Server 已配置为允许远程连接。”
“执行计划调用时间:,执行出错,出错时间:; 错误信息:远程服务器返回错误: (500) 内部服务器错误。”
导致执行计划有问题,日志库里的T_BAS_SCHEDULELOG 表都有记录系统标准执行计划于二开执行计划都有记录错误,但是二开的插件遇到该错误为 任务状态转为"异常",然后不会自动恢复异常(即时勾选了该选项)。这位客户造成了很大的困难。
其实这类问题,在C#编程中,要使用try跟catch,配合得当,就是这个周期遇到了该错误没执行,下个周期能执行到就行,由于周期间隔短,客户会没感知到该异常。
我写了个例子, 大概想法,是在后台数据库创建[Ldq_SZ]表,表中有1列为SZ,是自增列,插件先查询最大的SZ,然后再上循环100次,每次都加1,插入到表Ldq_SZ。创建表的代码如下
CREATE TABLE [dbo].[Ldq_SZ](
[SZ] [int] NOT NULL,
[DT] [datetime] NULL,
CONSTRAINT [PK_Ldq_SZ] PRIMARY KEY CLUSTERED
(
[SZ] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
C#代码如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.LogPlatform;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.Log;
using Kingdee.BOS.Core;
using Kingdee.BOS;
using Kingdee.BOS.DataEntity;
using System.Threading;
namespace ldq_IScheduleService_CF
{
public class ldq_IScheduleService : IScheduleService
{
public void Run(Context ctx, Kingdee.BOS.Core.Schedule schedule)
{
string sql = string.Empty;
int SZ_max = 0;
try
{
var max = DBUtils.ExecuteObject<Kingdee.BOS.Orm.DataEntity.DynamicObject>(ctx, " select max(SZ) as SZ from Ldq_SZ ");
SZ_max = Convert.ToInt32(max[0]["SZ"]);
}
catch (KDException e)
{
return;
}
for (int K = 1; K <= 100; K++)
{
sql = String.Format(" insert into Ldq_SZ ( SZ , DT) select {0}, getdate() ", Convert.ToString(SZ_max + K));
ldq_Execte(ctx,sql);
}
}
public void ldq_Execte(Context ctx, string sql)
{
Thread.Sleep(500);
try
{
DBUtils.Execute(ctx, sql);
}
catch (KDException e)
{
}
}
}
}
其效果是, 大概把表 Ldq_SZ 删除了, 该执行计划的任务状态还是在"运行".
另外,SZ是主键,就算插入到重复的主键,也是够健壮的。
推荐阅读