SQL Comparison SDK 10

Help for older versions available.

These pages cover SQL Comparison SDK 10, which is not the latest version. Help for other versions is also available.

Executing your own SQL queries together with SDK synchronization

When executing a synchronization script created by the SQL Comparison SDK, it may be desired that some ad-hoc queries be intermixed with the SQL produced by the Red Gate APIs.

Because the BlockExecutor class can only run SQL code by converting ExecutionBlocks to SQL code and submitting them to the SQL Server, custom SQL cannot be introduced into the query stream. It is possible, however, to break an ExecutionBlock into individual query batches and running them using the .NET Framework's ADO .NET methods.

In the following C# example, a SQL query SET LANGUAGE us_english needs to be submitted before the synchronization produced by the SQL Data Compare Engine. First, a connection is made to the server using the connection properties of the second database. Then a transaction is created. The custom SQL query is run first, then each batch of SQL from the ExecutionBlock in order. Finally, the transaction is committed. If any errors occur during the execution of the SQL script, then the error is written to the console and the transaction will be rolled back.

  1. using System;
  2. using RedGate.SQLCompare.Engine;
  3. using System.IO;
  4. using RedGate.Shared.SQL.ExecutionBlock;
  5. using System.Data.SqlClient;
  6. namespace CompareTwoDatabases
  7. {
  8. /// <summary>
  9. /// Demonstration that compares the widgetStaging database to the widgetProduction database
  10. /// and synchronizes them using the ADO .NET libraries
  11. /// </summary>
  12. class Program
  13. {
  14. static void Main(string[] args)
  15. {
  16. using (Database widgetStaging = new Database(),
  17. widgetProduction = new Database())
  18. {
  19. // Retrieve the schema information for the two databases
  20. widgetStaging.Register(new ConnectionProperties(".", "WidgetStaging"), Options.Default);
  21. widgetProduction.Register(new ConnectionProperties(".", "WidgetProduction"), Options.Default);
  22. // Compare widgetStaging to widgetProduction. Comparing in this order makes WidgetProduction the second database
  23. Differences stagingVsProduction = widgetStaging.CompareWith(widgetProduction, Options.Default);
  24. // Select the differences to include in the synchronization. In this case, we're using all differences.
  25. foreach (Difference difference in stagingVsProduction)
  26. {
  27. difference.Selected = true;
  28. }
  29. Work work = new Work();
  30. // Create the migration without the transactional bits --
  31. //we will let ADO .NET manage the transactions using SqlTransaction
  32. // The script is to be run on widgetProduction so the runOnTwo parameter is true
  33. work.BuildFromDifferences(stagingVsProduction, Options.Default | Options.NoSQLPlumbing,true);
  34. // We can now access the messages and warnings
  35. Console.WriteLine("Messages:");
  36. foreach (Message message in work.Messages)
  37. {
  38. Console.WriteLine(message.Text);
  39. }
  40. Console.WriteLine("Warnings:");
  41. foreach (Message message in work.Warnings)
  42. {
  43. Console.WriteLine(message.Text);
  44. }
  45. // Disposing the execution block when it's not needed any more is important to ensure
  46. // that all the temporary files are cleaned up
  47. using (ExecutionBlock block = work.ExecutionBlock)
  48. {
  49. // Display the SQL used to synchronize
  50. Console.WriteLine("SQL to synchronize:");
  51. Console.WriteLine(block.GetString());
  52. // Make a connection string from the second database connection properties (runOnTwo)
  53. System.Data.SqlClient.SqlConnection conn = newSystem.Data.SqlClient.SqlConnection("Data Source=" + widgetProduction.ConnectionProperties.ServerName +";Initial Catalog=" + widgetProduction.ConnectionProperties.DatabaseName + ";Integrated Security=SSPI");
  54. System.Data.SqlClient.SqlCommand cmd = conn.CreateCommand();
  55. conn.Open();
  56. SqlTransaction trans = conn.BeginTransaction("MyTransaction");
  57. cmd.Transaction = trans;
  58. //Run the first command
  59. cmd.CommandText = "SET LANGUAGE us_english";
  60. cmd.ExecuteNonQuery();
  61. //Run batches
  62. for (int i = 0; i < block.batchcount;="">
  63. {
  64. Batch b = block.GetBatch(i);
  65. try
  66. {
  67. if (!b.Marker) //Do not run blocks that are simply "GO"
  68. {
  69. cmd.CommandText = b.Contents;
  70. cmd.ExecuteNonQuery();
  71. }
  72. }
  73. catch (System.Data.SqlClient.SqlException se)
  74. {
  75. Console.WriteLine("Execute SQL failed: " + se.Message);
  76. trans.Rollback();
  77. }
  78. }
  79. trans.Commit();
  80. }
  81. Console.WriteLine("Press [Enter]");
  82. Console.ReadLine();
  83. }
  84. }
  85. }
  86. }

Didn't find what you were looking for?