我们正在尝试通过C#代码执行大量SQL脚本文件。
方案:
更多信息:如果所有脚本成功执行,然后Commit
正常工作,它运行良好。但是,如果中间的任何脚本失败,那么在脚本失败异常默认情况下系统Rollback
到目前为止已成功执行的所有脚本,我们将获得新的连接(自动)以执行其余脚本。在保留每个成功执行的单个文件之后,获取我们不想要的自动提交(因为完整的目的是,提交应该仅在所有脚本成功执行时才起作用)。
另一个问题:假设脚本-2是主DDL
脚本,脚本-7是脚本-2上的DML
语句。现在,如果在脚本-5上发生异常,那么系统将所有脚本回滚到5,并且我们自动获得新连接(我们不想要,我们希望只有一个事务通过)。对于脚本6,它可以正常工作,但对于脚本7,它会抛出错误,因为脚本7依赖于已经回滚的脚本2。但这是错误的。脚本2已成功执行并在脚本-5失败时强制回滚。因此,如果脚本5没有问题,则脚本7将成功执行。现在我们将看到脚本7上的错误正在消耗开发时间来修复它,但是根本没有错误,可能会有更多这样的脚本。
C#代码:
public dynamic ProcessScripts(string[] files, String _sqlconString, String DatabaseName)
{
string _buildNumber = Convert.ToString(System.Configuration.ConfigurationManager.AppSettings["BuildNumber"]).Trim();
dynamic objReturn = new ExpandoObject();
objReturn.IsExceptionOccured = false;
objReturn.DBName = "";
FileInfo file = null;
bool IsExceptionOccured = false;
string script = string.Empty;
string InsertScript = string.Empty;
SqlConnection _sqlconnection = new SqlConnection(_sqlconString);
ServerConnection _ServerConnection = new ServerConnection(_sqlconnection);
Server _serverk = new Server(_ServerConnection);
_serverk.ConnectionContext.BeginTransaction();
String _QueryString = string.Empty;
foreach (string s in files)
{
file = new FileInfo(s);
String FileName = file.Name.ToLower().Trim();
script = file.OpenText().ReadToEnd();
if (script.Trim() != string.Empty)
{
try
{
InsertScript = nl+"GO "+nl+" INSERT INTO [LOGTable] (FileName,STATUS,BUILD_NO) VALUES ('" + Path.GetFileName(s.ToString()) + "','success','" + _buildNumber + "'); "+nl+"GO "+nl;
_QueryString = FindAndReplace(script) + InsertScript;
_serverk.ConnectionContext.ExecuteNonQuery(_QueryString);
WriteLog(LogType.Execution, DatabaseName, null, "Execution succeed ", FileName);
}
catch (Exception ex)
{
string _Msg = string.Empty;
if (ex.InnerException != null)
_Msg = ex.InnerException.Message;
else
_Msg = ex.Message;
WriteLog(LogType.Execution, DatabaseName, new Exception(_Msg), "Execution Failed", FileName, "");
objReturn.IsExceptionOccured = true;
}
}
}
if (objReturn.IsExceptionOccured)
{
_serverk.ConnectionContext.RollBackTransaction();
}
else
{
_serverk.ConnectionContext.CommitTransaction();
}
return objReturn;
}