Блог программиста Еремина Вячеслава Викторовича
(NET) NET (2005 год)

Альтернативная оболочка к SQL2005

Одна из повседневных задач, решаемых любым программистом - синхронизация боевой и девелоперской базы. Она осложняется тем, что разработчиков может быть несколько, те для синхронизации надо выделять конкретную подсистему, продвигаемую конкретными девелопером. Но поскольку стандартных механизмов для этой задачи нет, а сторонние проги мне показались глючными, плюс возня с лекарствами... В, общем я решил написать свое...

После некоторого обдумывания, я решил все-таки остановится на технологии SMO, ибо без этого не вытащить из базы многих важнейших вещей. Начал я с вот такого скриптика:

00001: Imports Microsoft.SqlServer.Management.Smo
00002: Module Module1
00003:     Sub Main()
00004:         Dim Parm() As String = System.Environment.GetCommandLineArgs
00005:         If Parm.Length <> 4 Then
00006:             Console.WriteLine("Неправильный вызов этой проги")
00007:             Console.WriteLine("Первый параметр - имя сервера")
00008:             Console.WriteLine("Второй параметр - имя базы")
00009:             Console.WriteLine("Третий параметр - имя таблы")
00010:             Console.ReadLine()
00011:             Exit Sub
00012:         End If
00013:         Dim MyServer As Server = New Server(System.Environment.GetCommandLineArgs(1).ToString)
00014:         Dim MyDB As Database = MyServer.Databases(System.Environment.GetCommandLineArgs(2).ToString)
00015:         Dim MyScripter As Scripter = New Scripter(MyServer)
00016:         Dim MyTable As Table = MyDB.Tables(System.Environment.GetCommandLineArgs(3).ToString)
00017:         'Заскриптуем все обьекты базы через обьекты SMO
00018:         Dim MyScript As Collections.Specialized.StringCollection = MyScripter.Script(GetRelatedObject(MyTable))
00019:         'И на солнышко их вытащим
00020:         For Each one As String In MyScript
00021:             Console.WriteLine(one)
00022:         Next
00023:         Console.ReadLine()
00024:     End Sub
00025:     Private Function GetRelatedObject(ByVal MyTable As Table) As SqlSmoObject()
00026:         'сначала все обьекты, связанные с базой накопим в коллекцию, потом сбросим их в массив 
00027:         Dim MyScriptingObject As New Collection
00028:         Dim MySmoObjArr() As SqlSmoObject
00029:         'Сначала добавляем на скриптовку саму базу, потом все ее потроха
00030:         MyScriptingObject.Add(MyTable)
00031:         If MyTable.Indexes.Count > 0 Then
00032:             For Each OneIndex As Index In MyTable.Indexes
00033:                 MyScriptingObject.Add(OneIndex)
00034:             Next
00035:         End If
00036:         If MyTable.ForeignKeys.Count > 0 Then
00037:             For Each OneKeys As ForeignKey In MyTable.ForeignKeys
00038:                 MyScriptingObject.Add(OneKeys)
00039:             Next
00040:         End If
00041:         If MyTable.Checks.Count > 0 Then
00042:             For Each OneCheck As Check In MyTable.Checks
00043:                 MyScriptingObject.Add(OneCheck)
00044:             Next
00045:         End If
00046:         If MyTable.Triggers.Count > 0 Then
00047:             For Each OneTrigger As Trigger In MyTable.Triggers
00048:                 MyScriptingObject.Add(OneTrigger)
00049:             Next
00050:         End If
00051:         'Наконец, сбросим коллекцию в массив
00052:         MySmoObjArr = CType(Array.CreateInstance(GetType(SqlSmoObject), MyScriptingObject.Count), SqlSmoObject())
00053:         For i As Integer = 0 To MyScriptingObject.Count - 1
00054:             MySmoObjArr(i) = CType(MyScriptingObject(i + 1), SqlSmoObject)
00055:         Next
00056:         GetRelatedObject = MySmoObjArr
00057:     End Function
00058: End Module

Который отработал весьма удачно:




Увы, в NET/CLR-сборку SMO, включить не удалось, из-за того, что SMO ссылается на сборку Microsoft.SqlServer.BatchParser, которая является Wrapper'ом COM-класса. Но тем не менее, как COM-обьект эта прога себя хорошо зарекомендовала для скриптовки структуры базы:




Однако, ForeignKey мне так заскриптовать не удалось, несмотря на все мои потуги. К тому же, прога получилась только для скриптовки структуры таблиц, а у меня в девелоперской базе только Джобов 60 штук. Не говоря уже обо всяких Proxy_Account'ах и прочем. Поэтому я решил сделать полноэкранное приложение. Получилась примерно такая штука: