2015-09-11 2 views
1

Команда разработчиков, с которыми я работаю, использует SQL Data Projects для большой работы, которую мы должны делать против существующей базы данных. Мы находимся несколько недель, и было несколько ошибок, но опыт был в целом хорош.SQL Server ScriptDom Parsing

Однако, когда мы добираемся до развертывания, команда dba отказалась принимать DACPAC как метод развертывания. Вместо этого они хотят видеть традиционный скрипт для DML или DDL-оператора.

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

Чтобы разобрать разница сценарий, кажется, два варианта:

  1. Разобрать скрипт на основе команды пакетного сепаратора, GO. Это довольно простые решения, но они обещают.
  2. Или используйте Microsoft.SqlServer.TransactSql.ScriptDom. Это выглядит более перспективным, но кажется гораздо более сложным.

В настоящий момент я тестирую ScriptDom, но мне трудно понять его. Мои текущие, но не только проблемы, заключаются в следующем.

Я пытаюсь разобрать следующий SQL с помощью ScriptDOM в C#:

CREATE TABLE dbo.MyTable 
(
    MyColumn VARCHAR(255) 
) 

Но не могу видеть, как получить доступ размера VARCHAR, в этом случае 255.

Код I» м используется следующим образом:

TSqlFragment sqlFragment = parser.Parse(textReader, out errors); 

SQLVisitor myVisitor = new SQLVisitor(); 
sqlFragment.Accept(myVisitor); 

public override void ExplicitVisit(CreateTableStatement node) 
{ 
    // node.SchemaObjectName.Identifiers to access the table name 
    // node.Definition.ColumnDefinitions to access the column attributes 
} 

Из каждого определения столбца я ожидал найти свойство длины или подобное. Тем не менее, у меня также есть подозрение, что вы можете использовать шаблон посетителя, с которым я сталкиваюсь, для повторного анализа каждого определения столбца. Любые идеи?

ответ

3

Отлично, что вы используете ssdt!

Самый простой способ справиться с этим, когда у вас есть DBA, который не хочет работать с dacpacs, состоит в том, чтобы предварительно сгенерировать сценарий deloyment с помощью sqlpackage.exe.

Как мне сделать это ...

  • Проверочный код T-SQL в проекте
  • сервер сборки строит SSDT проекту
  • Deploy и выполнения тестов на сервере CI
  • использовать sqlpackage. exe/action: скрипт для сравнения dacpac с QA, PROD и т. д. и генерация сценария развертывания.

После этого DBA берет этот сценарий (или когда мы готовы сообщить им номер сборки для захвата) - они могут изучить и развернуть этот скрипт.

Things отметить:

  • Вам необходим доступ к прод дб или зеркало копии вы можете использовать, вам не нужно DBO или что-либо только права доступа в (https://the.agilesql.club/Blogs/Ed-Elliott/What-Permissions-Do-I-Need-To-Generate-A-Deploy-Script-With-SSDT)
  • скриптах действительны только до тех пор, пока не изменится схема в prod db - поэтому, если вы создаете 4 сценария и запускаете сценарий 1, остальные три являются недопустимыми, и вам нужно будет повторно запустить сборку для генерации скрипта.

Если у вас нет установки CI вы можете просто использовать sqlpackage.exe для создания сценария без автоматических бит :)

Надеется, что это помогает!

ред

+0

У нас есть все шаги, которые вы упомянули выше, хотя есть «обсуждения» с использованием SQL Test Project, но я отвлекаюсь. Проблемы, которые у меня есть, это то, что dba хочет, чтобы один файл сценария изменялся не на один скрипт со всеми изменениями. Среди множества параметров, которые вы можете передать в SQLPackage, я не видел, чтобы один из них указывал использование нескольких выходных файлов. Следовательно, необходимо проанализировать вывод SQLPackage. В любом случае. –

+0

1 скрипт за изменение? это даже не имеет смысла - если у вас есть сто изменений, они хотят запустить 100 скриптов? В каком порядке они будут запускать их и что вы будете делать с пост-развертывающими сценариями. Я попытался бы выяснить, как заставить их принять один сценарий развертывания, иначе вы просите мир боли (для них и для вас) –

+0

Я могу только согласиться с тем, что это не имеет большого смысла. У команды dba есть домашний инструмент, который они используют для запуска скриптов. Разработчики должны завершить распространение Excel, определяющее местоположение в системе управления версиями, порядок запуска сценариев, целевой сервер и базу данных. Затем DBA используют это для развертывания изменений. Затем скрипты вывода становятся доступными для разработчиков. Это нормально для команды dba, поскольку это делает их жизнь простой, но для разработчиков это боль. Отсюда причина, по которой команда DBA не спешит искать лучшее решение, такое как dacpac. –

3

Я не думаю, что нужно посетителю здесь вообще. Если я правильно понимаю вашу цель, вы хотите использовать TSQL, сгенерированный SSDT, проанализировать его с помощью SQLDOM и затем распечатать партии по отдельности. Код, чтобы сделать это будет выглядеть примерно так:

using System; 
using System.Collections.Generic; 
using System.IO; 
using Microsoft.SqlServer.TransactSql.ScriptDom; 

namespace ScriptDomDemo 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      TSql120Parser parser = new TSql120Parser(false); 
      IList<ParseError> errors; 
      using (StringReader sr = new StringReader(@"create table t1 (c1 int primary key) 
GO 
create table t2 (c1 int primary key)")) 
      { 
       TSqlFragment fragment = parser.Parse(sr, out errors); 
       IEnumerable<string> batches = GetBatches(fragment); 
       foreach (var batch in batches) 
       { 
        Console.WriteLine(batch); 
       } 
      } 
     } 

     private static IEnumerable<string> GetBatches(TSqlFragment fragment) 
     { 
      Sql120ScriptGenerator sg = new Sql120ScriptGenerator(); 
      TSqlScript script = fragment as TSqlScript; 
      if (script != null) 
      { 
       foreach (var batch in script.Batches) 
       { 
        yield return ScriptFragment(sg, batch); 
       } 
      } 
      else 
      { 
       // TSqlFragment is a TSqlBatch or a TSqlStatement 
       yield return ScriptFragment(sg, fragment); 
      } 
     } 

     private static string ScriptFragment(SqlScriptGenerator sg, TSqlFragment fragment) 
     { 
      string resultString; 
      sg.GenerateScript(fragment, out resultString); 
      return resultString; 
     } 
    } 
} 

А как работать с этим НРХОМ, я считаю, что проще в использовании отладчика Visual Studio для визуализации дерева, потому что вы можете увидеть фактический тип каждого узла и всех его свойств. Как вы можете видеть, для разбора TSQL требуется всего лишь немного кода.

+0

Я сделал демонстрацию, используя ваш код, и это лучший способ разбора кода, чем писать собственный код для поиска партии с завершением, GO. Одна часть, которую я не понял, был в вашем методе GetBatches, у вас есть оператор IF \ ELSE, и я не вижу, когда будет выполняться часть ELSE. Спасибо за ваш ответ. –

0
#reference Microsoft.SqlServer.BatchParser 
#reference Microsoft.SqlServer.BatchParserClient 

using System; 
using System.Collections.Specialized; 
using System.IO; 
using System.Text; 
using Microsoft.SqlServer.Management.Common; 

namespace ScriptParser 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
     ExecuteBatch batcher = new ExecuteBatch(); 
     string text = File.ReadAllText("ASqlFile.sql"); 
     StringCollection statements = batcher.GetStatements(text); 
     foreach (string statement in statements) 
     { 
      Console.WriteLine(statement); 
     } 
     } 
    } 
} 
Смежные вопросы