Options

Saving Contents of BlockExecutor for Later Execution

bazza47bazza47 Posts: 7
edited October 29, 2007 7:51AM in SQL Toolkit Previous Versions
After comparing two database schemas using the SQL Toolkit 6 API, I can save the changes to a file as follows:
string filePath = GetCachedScriptFilePath(targetDatabaseName);
BlockSaver saveBlock = new BlockSaver(filePath, EncodingType.UTF8, work.ExecutionBlock);
saveBlock.SaveToFile();

Is it possible to use the API to load the contents of the file, at some later time, and then apply these changes?

I tried code as follows, to apply the script contents, but the BlockExecutor doesnt like the 'GO's in the script. If I take the GOs out the the BlockExecutor fails because variables are defined more than once etc.
string scriptWithoutGO = String.Empty;
using (StreamReader sr = new StreamReader(cachedScriptFilePath))
{
    string script = sr.ReadToEnd();
    sr.Close();
    //scriptWithoutGO = script.Replace("GO", " ");   // nuke any GO's
    scriptWithoutGO = script;                       // or try with GO's
}

using (RedGate.SQLCompare.Engine.Database dbTarget = new RedGate.SQLCompare.Engine.Database())
{
    RedGate.SQL.Shared.BlockExecutor b = new BlockExecutor();
    using (ExecutionBlock blk = new ExecutionBlock())
    {
        blk.AddBatch(scriptWithoutGO);
        b.ExecuteBlock(blk, dataSource, targetDatabaseName, true, String.Empty, String.Empty);
    }
}

We have a large number of databases we need to sync and storing the changes to a script file for subsequent execution could lead to a reduction in processing time.

Thanks
Colin

Comments

  • Options
    The script which is saved using BlockSaver is designed to be run with Management Studio or similar tools.

    There are two approaches you could take to saving an execution block:

    1) Save the script and then run it 'by hand', i.e. using something like the following:
    public static void executeSql(string fileName, SqlConnection connection, bool reportErrors)
            {
                string sqlScript;
    
                using (StreamReader sr = new StreamReader(fileName))
                {
                    sqlScript = sr.ReadToEnd();
                }
    
                Regex r = new Regex("\\sGO\\s");
                string[] sqlScriptParts = r.Split(sqlScript);
    
                try
                {
                    connection.Open();
    
                    foreach (string sql in sqlScriptParts)
                    {
                        SqlCommand command = new SqlCommand(sql, connection);
                        try
                        {
                            command.ExecuteNonQuery();
                        }
                        catch (Exception e)
                        {
                            if (reportErrors) throw;
                            Console.WriteLine("Error executing command: " + command.CommandText);
                            Console.WriteLine("Error was: " + e);
                            continue;
                        }
                        finally
                        {
                            command.Dispose();
                        }
                    }
                }
                finally
                {
                    connection.Dispose();
                }
            }
    

    2) Serialize the actual ExecutionBlock object out to disk somehow, and read it back in into an ExecutionBlock object directly. I'm not entirely sure how or if this would work - I can look into it further if the above method won't do.
    Software Developer
    Redgate Software
Sign In or Register to comment.