创建SQLXAgent数据库的过程比预期的要复杂一些。想要能够在脚本运行时报告进度,这就需要一个接口,意味着负责创建数据库的代码必须是“可通知”的。为了使“可通知”这个术语有意义,不得不将一个大脚本拆分成35个独立的脚本文件。在测试代码的过程中,发现SQL Server(Express?)不支持批量查询中的GO语句。还发现,通过批量查询创建存储过程需要CREATE PROCEDURE行是查询中出现的第一个非注释行。
运行脚本的过程因为将它们作为(非复制的)嵌入资源包含进来而变得不那么繁琐,所以可以处理所有涉及表的查询,然后通过循环处理存储过程。以下是运行存储过程查询的方法。
private bool AddStoredProcs()
{
bool result = true;
string[] procs = this.assy.GetManifestResourceNames().Where(x => x.IsLike("%SQLXAgent_SP_%")).ToArray();
DBObject2.ConnectionString = this.sqlxConnStr;
foreach (string name in procs)
{
string[] parts = name.Split('.');
string filename = string.Concat(parts[parts.Length - 2], '.', parts[parts.Length - 1]);
string info = filename.Replace("SQLXAgent_", "").Replace("SP_", "sp_");
if (!this.RunSQLCommandFromFile(filename, string.Concat("Create proc ", info.Substring(0, info.IndexOf(".")))))
{
result = false;
break;
}
}
return result;
}
当开始测试调度代码时,观察到,给定作业的每次后续运行都会在预期的开始时间之后几秒钟开始运行。为了解决这个问题,在RunSchedule方法的开始重新计算下一次运行时间,同时将秒数归零。
问题在于有多款应用程序需要在SQLXAgent中修改某些设置。解决方案是“映射”SQLXAgent.exe.config文件,这样就可以从解决方案中的任何应用程序加载它。以下是使用的代码。
ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap() { ExeConfigFilename = this.ConfigFile };
this.AppConfig = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
即使是拥有该文件的应用程序——SQLXAgent——也使用了上面的代码(通过SQLXAgentSettings程序集中的静态类方便地提供)。这使得下游的事情变得简单得多。