Как выполнить большой SQL-скрипт с большим количеством операторов GO из Delphi?

У нас есть приложение для обновления, которое выполняет сценарии SQL из более чем 30 000 строк кода в базе данных SQL Server. В этом скрипте большое количество операторов GO. Компоненты ADO, к которым я привык, не поддерживают оператор GO. Мы всегда использовали командную строку OSQL при обновлении сервера, что сложно для обнаружения проблем (выводит текстовый файл, который мы затем должны анализировать для поиска ошибок и результатов). Было бы намного лучше, если бы что-то в Delphi могло находить эти GO оператора и выполнять каждый блок за раз.

Я понимаю, что оператор GO относится к инструментам MS, которые могут их выполнять. Опять же, сценарий состоит из более чем 30 000 строк кода, по крайней мере, с 500 операторами GO. Мы используем один и тот же сценарий в SQL Management Studio и OSQL для средства обновления. Но OSQL просто не дает нам нужных результатов — это неаккуратный способ выполнения такого сценария.

Существует ли какой-либо инструмент, совместимый с SQL Server для Delphi, который распознает операторы GO? Я не говорю обязательно о синтаксическом анализаторе (хотя я уверен, что синтаксический анализ будет задействован), я говорю о готовой утилите для выполнения сценариев SQL, которые содержат операторы GO и возвращают результаты каждого блока сценария.

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

ОБНОВЛЕНИЕ

Я успешно написал небольшой рабочий код, который делает это, однако он не принимает во внимание оператор GO в блоке комментариев.

Код найден здесь

Я больше ничего не спрашиваю в этом вопросе, просто подумал, что поделюсь, где я с этим.


person Jerry Dodge    schedule 08.08.2013    source источник
comment
И просто поиск строки GO тоже не сработает, потому что там, вероятно, есть строка, которая вставляет/обновляет некоторый текст со словом go   -  person Jerry Dodge    schedule 08.08.2013
comment
Ответа я не знаю, но я бы предложил поместить весь этот скрипт в одну хранимую процедуру и немного изменить ее, чтобы результаты каждой операции записывались в набор выделенных временных таблиц, которые перезаписываются при каждом запуске, например что результаты сценария можно различить по конкретным запросам к этим временным таблицам. Мои дни работы с хранилищами данных научили меня ценности временных таблиц в длительных и сложных операциях с базами данных, особенно когда большая часть обработки выполняется самой СУБД. Просто предложение. ХТН.   -  person Sam    schedule 08.08.2013
comment
Итак, ответ таков: мне решать, как выполнять SQL-скрипты. Сладкий! Теперь я могу написать свой собственный компонент для этого.   -  person Jerry Dodge    schedule 08.08.2013
comment
И что еще хуже, GO сам по себе непостоянен. Вы можете, например. configure your own batch terminator в Management Studio, чтобы вы могли сгенерировать скрипт с разделителем GOJOHNNYGO, например.   -  person TLama    schedule 08.08.2013
comment
Но я по-прежнему считаю, что соответствующие компоненты должны иметь такую ​​​​настраиваемую опцию, например, например. AnyDAC (или FireDAC) имеет для своего TADScript или, например, UniDAC за его TDAScript. Поэтому я думаю, что ваш вопрос также зависит от того, какие компоненты вы можете использовать.   -  person TLama    schedule 08.08.2013
comment
В продолжение комментария TLama я почти уверен, что Unidac от Devart позволит вам выполнить сценарий. Вы можете получить бесплатную пробную версию на Devart (devart.com/unidac), чтобы опробовать ее.   -  person Sam M    schedule 08.08.2013
comment
@SirRufo, принятый ответ этого дубликата, а также ответ Кена отсюда не принимают во внимание то, что упомянул Джерри here в комментарии; использование комментария SQL, такого как /*GO*/, написанного в 3 строки, где только это GO будет единственным словом в одной строке, но внутри комментария скрипта.   -  person TLama    schedule 08.08.2013
comment
Еще одна вещь, которую я понял в том же духе, это оператор USE...   -  person Jerry Dodge    schedule 08.08.2013
comment
Команда USE является обычным оператором, а GO — нет. Во всяком случае, просто чтобы добавить об этих исполнительных компонентах сценария; они также сами разбирают скрипт вручную.   -  person TLama    schedule 08.08.2013
comment
Джерри: Это может помочь:weblogs.asp.net/jgalloway/archive /2006/11/07/Обработка-2200_GO_2200-Separators-in-SQL-Scripts-2D00-the-easy-way.aspx   -  person MartynA    schedule 09.08.2013


Ответы (2)


Загрузка скрипта в TStringList будет работать. поиск слова GO в отдельной строке (что позволяет избежать встроенного текста, содержащего GO) в конце каждого блока или самого скрипта.

Вы используете индекс строки GO - 1, чтобы отметить конец предыдущего блока, и индекс строки GO + 1, как начало следующего блока. Если индекс GO равен StringList.Count - 1, вы достигли конца скрипта. Вы можете запустить транзакцию перед обработкой блоков и откатить эту транзакцию, если возникнет исключение.

person Ken White    schedule 08.08.2013
comment
Будем надеяться, что GO находятся на отдельной строке... Но комментарии разрешены только в той же строке (см. msdn.microsoft.com/en-us/library/ms188037.aspx). Вам также придется обрабатывать GO внутри /* блочного комментария */ - person Gerry Coll; 08.08.2013
comment
@Gerry: Оба хороших момента. С первым можно справиться, взглянув конкретно на первые три символа GO;. Второй может быть обработан логическим флагом InComment. Я никогда не говорил, что вам не придется немного поработать, будь то настройка скрипта или код, который его обрабатывает. ИМО, это по-прежнему лучшее решение, так как я не нашел ни одного из тех, которые работают правильно. - person Ken White; 08.08.2013

На самом деле это хороший вопрос, на который нет простого ответа.

Стоит подчеркнуть, что это проблема Microsoft, а не SQL и не Delphi.

Это много раз обсуждалось на SO, но нет универсального ответа:

Два моих основных предложения:

  • Прочитайте файл сценария, проанализируйте его построчно и запустите «выполнить» после каждой строки, содержащей только «go».

  • Выполните ShellExecute() (или эквивалент) SqlCmd.exe с параметрами сценария и входа в систему.

person paulsm4    schedule 08.08.2013