我有一个C#方法来执行SQL作业.它成功执行SQL作业.代码工作得很完美.我正在使用标准SQL存储过程msdb.dbo.sp_start_job.这是我的代码..public int ExcecuteNonquery(){var result = 0;using (var execJob =new SqlC...
我有一个C#方法来执行SQL作业.它成功执行SQL作业.
代码工作得很完美.
我正在使用标准SQL存储过程msdb.dbo.sp_start_job.
这是我的代码..
public int ExcecuteNonquery()
{
var result = 0;
using (var execJob =new SqlCommand())
{
execJob.CommandType = CommandType.StoredProcedure;
execJob.CommandText = "msdb.dbo.sp_start_job";
execJob.Parameters.AddWithValue("@job_name", "myjobname");
using (_sqlConnection)
{
if (_sqlConnection.State == ConnectionState.Closed)
_sqlConnection.Open();
sqlCommand.Connection = _sqlConnection;
result = sqlCommand.ExecuteNonQuery();
if (_sqlConnection.State == ConnectionState.Open)
_sqlConnection.Close();
}
}
return result;
}
这是在作业内执行的sp
ALTER PROCEDURE [Area1].[Transformation]
AS
BEGIN
SET NOCOUNT ON;
SELECT NEXT VALUE FOR SQ_COMMON
-- Transform Master Data
exec [dbo].[sp_Transform_Address];
exec [dbo].[sp_Transform_Location];
exec [dbo].[sp_Transform_Product];
exec [dbo].[sp_Transform_Supplier];
exec [dbo].[sp_Transform_SupplierLocation];
-- Generate Hierarchies and Product References
exec [dbo].[sp_Generate_HierarchyObject] 'Area1',FGDemand,1;
exec [dbo].[sp_Generate_HierarchyObject] 'Area1',RMDemand,2;
exec [dbo].[sp_Generate_Hierarchy] 'Area1',FGDemand,1;
exec [dbo].[sp_Generate_Hierarchy] 'Area1',RMDemand,2;
exec [dbo].[sp_Generate_ProductReference] 'Area1',FGDemand,1;
exec [dbo].[sp_Generate_ProductReference] 'Area1',RMDemand,2;
-- Transform Demand Allocation BOM
exec [Area1].[sp_Transform_FGDemand];
exec [Area1].[sp_Transform_FGAllocation];
exec [Area1].[sp_Transform_RMDemand];
exec [Area1].[sp_Transform_RMAllocation];
exec [Area1].[sp_Transform_BOM];
exec [Area1].[sp_Transform_RMDemand_FK];
-- Transform Purchasing Document Data
exec [dbo].[sp_Transform_PurchasingDoc];
exec [dbo].[sp_Transform_PurchasingItem];
exec [dbo].[sp_Transform_ScheduleLine];
exec [dbo].[sp_CalculateRequirement] 'Area1'
exec [dbo].[sp_Create_TransformationSummary] 'Area1'
-- Trauncate Integration Tables
exec [dbo].[sp_TruncateIntegrationTables] 'Area1'
END
问题是,即使作业成功执行或不成功,它总是返回-1.如何识别作业是否成功执行.
解决方法:
运行msdb.dbo.sp_start_job后,返回代码将映射到输出参数.您有机会在执行之前控制参数的名称:
public int StartMyJob( string connectionString )
{
using (var sqlConnection = new SqlConnection( connectionString ) )
{
sqlConnection.Open( );
using (var execJob = sqlConnection.CreateCommand( ) )
{
execJob.CommandType = CommandType.StoredProcedure;
execJob.CommandText = "msdb.dbo.sp_start_job";
execJob.Parameters.AddWithValue("@job_name", "myjobname");
execJob.Parameters.Add( "@results", SqlDbType.Int ).Direction = ParameterDirection.ReturnValue;
execJob.ExecuteNonQuery();
return ( int ) sqlCommand.Parameters["results"].Value;
}
}
}
您需要知道返回代码的数据类型才能执行此操作 – 对于sp_start_job,它是SqlDbType.Int.
但是,这只是启动工作的结果,值得了解,但不是运行工作的结果.要使结果运行,您可以定期执行:
msdb.dbo.sp_help_job @jobName
该过程返回的一个列是last_run_outcome,可能包含您真正感兴趣的内容.当它仍在运行时,它将是5(未知).
工作通常是许多步骤 – 其中每个步骤可以根据先前步骤的结果执行,也可以不执行.另一个名为sp_help_jobhistory的过程支持大量过滤器,以指定您感兴趣的作业的特定调用和/或步骤.
SQL喜欢将工作视为计划工作 – 但是没有什么可以阻止您只是临时启动工作 – 虽然它并没有真正为您提供大量支持来将您的临时工作与实例相关联是工作历史.日期和它一样好(除非有人知道我不知道的伎俩.)
我已经看到作业在运行之前创建了临时作业的??位置,因此当前的临时执行是唯一返回的执行.但是你最终会遇到许多重复或接近重复的工作,这些工作永远不会再被执行.如果你走那条路,你必须计划事后清理的东西.
关于使用_sqlConnection变量的注释.你不想那样做.你的代码处理它,但它显然是在调用此方法之前在别处创建的.这是糟糕的juju.你最好只创建连接并以相同的方法处理它.依靠SQL连接池来快速建立连接 – 这可能已经打开了.
另外 – 在您发布的代码中 – 看起来您开始使用execJob但是切换到sqlCommand – 并且有点混乱编辑.我假设你的意思是execJob一直通过 – 这反映在例子中.
本文标题为:如何识别C#中是否成功执行SQL作业
基础教程推荐
- 详解c# PLINQ中的分区 2023-03-04
- C#实现坦克大战游戏 2023-03-04
- C#面向对象设计原则之单一职责原则 2023-05-25
- Unity shader实现顶点动画波动效果 2023-02-16
- C#多种操作excel的方法比较 2023-05-11
- unity 如何获取button文本的内容 2023-04-14
- 深入理解C#委托delegate的使用 2023-06-27
- C# 拼图魔方小游戏 2023-02-08
- 详解C#压缩、解压文件夹/文件(带密码) 2023-03-10
- C#中的反射(System.Reflection) 2023-06-08