как сохранить хранимые процедуры SQL в файлы .sql через пакет - PullRequest
9 голосов
/ 20 февраля 2009

Мне бы хотелось автоматически сохранять хранимые процедуры MS SQL Server 2005 в файлы .sql (предпочел бы инструмент, который я могу вызвать через .bat), поэтому мне не нужно вручную нажимать каждый отдельный фрагмент и сохранять его.

Я уже нашел SMOscript от devio IT, но он собирает все таблицы и sproc, что занимает некоторое время. Есть ли подобный инструмент, где я могу определить, какие sproc (ы) для экспорта? Также мне не хватает предложения USE, которое SMOScript не добавляет в экспортируемый файл, в отличие от ручного экспорта как сценария sproc для CREATE.

С наилучшими пожеланиями Sean

Ответы [ 7 ]

5 голосов
/ 20 февраля 2009

Создать пакетный файл со скриптом (извините за форматирование, но он действительно должен быть встроенным, чтобы выполнить пакет):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -o "sp_list.txt"
for /f %%a in (sp_list.txt) do osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -o "%%a.sql"

Назовите его "run.bat". Теперь, чтобы выполнить партию, используйте параметры:
run.bat [имя пользователя] [пароль] [имя_сервера] [база данных]
на примере:
run.bat sa pwd111 localhost \ SQLEXPRESS master
сначала все имена хранимых процедур будут храниться в файле sp_list.txt, затем одно за другим в отдельных файлах сценариев. Единственная проблема - последняя строка каждого скрипта с подсчетом результатов - я работаю над этим :)

отредактировано : исправлена ​​ошибка в запросе

Удаление строки "Затронутые строки"
Хорошо, теперь нам нужно создать еще одну партию:

type %1 | findstr /V /i %2  > xxxtmpfile 
copy xxxtmpfile %1 /y /v
del xxxtmpfile

Назовите его "line_del.bat". Смотрите, первый параметр - это файл для обработки, второй - строка для поиска строк для удаления. Теперь измените основной пакет (опять же извините за форматирование):

osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -n -o "sp_list.txt"
call line_del sp_list.txt "rows affected"
call line_del sp_list.txt "row affected"
for /f %%a in (sp_list.txt) do osql -U %1 -P %2 -S %3 -d %4 -h-1 -Q "SELECT ROUTINE_DEFINITION FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_NAME = '%%a'" -n -o "%%a.sql" 
for /f %%a in (sp_list.txt) do call line_del %%a.sql "rows affected"
for /f %%a in (sp_list.txt) do call line_del %%a.sql "row affected"

См. Статьи по теме:
Простые команды программирования в пакетной среде
Утилита osql
MSSQL: Как выполнить сценарий создания хранимой процедуры с помощью кода?
Удалить определенные строки в текстовом файле через командный файл

:) вы можете заметить, последние два из SO!

2 голосов
/ 20 февраля 2009

В SQL Server Management Studio есть альтернатива, сценарий для базы данных ...

Раскройте представление Object Explorer, чтобы найти базу данных, щелкните правой кнопкой мыши и выберите «Задачи: Генерация сценариев»

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

Сделав эту опцию «ЛОЖЬ», вы просто получите полный список операторов CREATE.

Затем можно выбрать сценарий для объектов в новом окне запроса или файле.

1 голос
/ 02 августа 2011

Добавление SET NOCOUNT ON действительно исключило необходимость в line_del.bat, но замена syscomments на sys.sql_modules привела к тому, что каждая хранимая процедура была усечена до 258 символов. Поэтому для достижения наилучших результатов я использовал следующий код:

sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt"
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER-d DB -h-1 -Q "SET NOCOUNT ON SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql"

Который работал и не нуждался в использовании line_del.bat. Что я не получил, когда сделал экспорт вручную с помощью мастера SSMS (Задачи / Генерация сценариев / Хранимые процедуры / Выбрать все):

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

в начале каждого .sql, а также завершающая команда GO. Не очень важно, но кое-что стоит отметить. Спасибо Максу Гонтару, Seansilver и Lee за ваш вклад! Теперь я могу автоматизировать резервное копирование хранимых процедур в базе данных и применить контроль версий.

0 голосов
/ 07 октября 2011

Спасибо всем выше за помощь и оставил это здесь для других noobs sqlcmd, чтобы найти. Работает на SQL Server 2005. ObjectName - это процедура, представление и т. Д. Name.

:reset

-- :setvar ObjectName "objectName"  -- works
:setvar ObjectName objectName  -- works too
declare @sql varchar(max);
set @sql = 'select text from dbo.syscomments where id = object_id(upper("' + '$(ObjectName)' + '"))';
-- exec sp_helptext $(ObjectName)  -- quick n easy but gets chopped to 256 width
/*   4000 byte limit
set @sql = 
   'select view_definition 
    from information_schema.views 
    where upper(table_name) = upper("' + '$(ObjectName)' + '")';
*/
:out $(ObjectName).sql

exec(@sql)
go

:out stdout
0 голосов
/ 07 мая 2009

Я добавил SET NOCOUNT ON, чтобы исключить необходимость в line_del.bat. Также заменены syscomments на sys.sql_modules (SQL 2005). Я мог бы также использовать функцию OBJECT_DEFINITION, но она была медленнее, чем sys.sql_modules.

sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt" for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SET NOCOUNT ON SELECT definition from sys.sql_modules WHERE object_id = OBJECT_ID('%%a')" -o "%%a.sql"
0 голосов
/ 24 февраля 2009

Я использовал sqlcmd и -E вместо пользователя, pass. Пока это работает нормально, только хранимые процедуры длиннее 4000 символов будут иметь разрыв строки

sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.Routines WHERE ROUTINE_TYPE = 'PROCEDURE'" -o "sp_list.txt"
call line_del sp_list.txt "rows affected"
call line_del sp_list.txt "row affected"
for /f %%a in (sp_list.txt) do sqlcmd -E -S SERVER -d DB -h-1 -Q "SELECT text from dbo.syscomments WHERE id = OBJECT_ID('%%a')" -o "%%a.sql"
for /f %%a in (sp_list.txt) do call line_del %%a.sql "rows affected"
for /f %%a in (sp_list.txt) do call line_del %%a.sql "row affected"

С наилучшими пожеланиями Sean

0 голосов
/ 20 февраля 2009

Некоторое время назад я хотел сделать то же самое, и в итоге я сделал небольшой VBScript.

Смотрите здесь Контроль источника и хранимые процедуры

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...