SMO事务通过C#代码

时间:2016-08-10 05:05:35

标签: c# sql sql-server-2008 smo sqltransaction

我们正在尝试通过C#代码执行大量SQL脚本文件。

方案:

  1. 我们希望在SQL Server上执行所有脚本文件。如果成功执行 所有脚本然后提交事务,否则回滚所有内容。
  2. 如果文件成功执行,则将其记录在表格中,以便我们将其记录下来 不要再拿它了。
  3. 我们希望继续执行所有脚本,以便我们可以一次性捕获所有文件中的错误。但是如果发生任何异常,那么任何文件代码都不应该被提交。
  4. 更多信息:如果所有脚本成功执行,然后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;
    
    }
    

0 个答案:

没有答案