2015-02-04 2 views
2

У меня есть SQL-скрипт, который мне нужно запустить примерно на 20 разных базах данных.Запуск файла .sql в SQL-запросе

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

Я надеялся сделать SQL скрипт, который будет в основном выглядеть примерно так:

use database1 
go 
exec c:\release.sql 
go 

use database2 
go 
exec c:\release.sql 
go 

use database3 
go 
exec c:\release.sql 
go 

--etc ....

Я посмотрел в Интернете кучу и нашел способ сделать что-то подобное в пакетном файле с SQLCMD но он не работает, и я не вижу, как переключать базы данных таким образом.

Спасибо тонну!

Бен

+2

не работает? Это потому, что ваш экран не включен? –

+0

Возможный дубликат [TransactSQL для запуска другого сценария TransactSQL] (http://stackoverflow.com/questions/5237198/transactsql-to-run-another-transactsql-script) –

ответ

5

Вы можете переключить студию управления в режим (меню запроса) Sqlcmd, а затем запустить сценарий с :r script.sql

Чтобы сделать это на динамически генерируемый список баз данных вы должны сделать некоторые Sqlcmd фокусы:

  • набора вывод в файл
  • генерировать команды для выполнения
  • набора вывода стандартный вывод
  • выполнить файл
  • удалить временный файл

я предполагаю, что в этом примере файл script.sql существует в c:\temp. Обратите внимание, что операторы GO важны в скрипте, или парсер sqlcmd будет запутан.

:OUT $(TEMP)\db.sql 
declare @script nvarchar(max) 
select @script = isnull(@script, '') 
       + 'use ' + name + char(13) + char(10) 
       + ':r c:\temp\script.sql' + char(13) + char(10) 
    from sys.databases 
where name like N'%[_]db' 
print @script 

GO 

:OUT stdout 
:r $(TEMP)\db.sql 

GO 

!!del $(TEMP)\db.sql /s /q 
+0

В итоге я объединил 2 вещи. Я создал SQL-скрипт, который создает курсор для поиска баз данных, а затем распечатывает список команд для приглашения CMD. Затем я запустил это в командной строке. – Funkymonk

+0

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

+0

Я обновил ответ, чтобы он соответствовал новому вопросу. –

1

Вам не нужно это делать в SSMS. Вам просто нужно создать сценарий CMD.

IF у вас есть статический набор баз данных для запуска на, затем используйте следующую команду:

@ECHO OFF 

SET MyServer="(local)" 
SET MyScript="c:\release.sql" 

SQLCMD -S %MyServer% -E -i %MyScript% -d database1 
SQLCMD -S %MyServer% -E -i %MyScript% -d database2 
... 
SQLCMD -S %MyServer% -E -i %MyScript% -d database20 

IF у вас есть динамический набор баз данных, которые могут быть запрошены для, затем используйте следующие :

@ECHO OFF 

SET MyServer="(local)" 
SET MyScript="c:\release.sql" 
SET MyQuery="SET NOCOUNT ON; SELECT [Name] FROM [sys].[databases] sd WHERE sd.[name] LIKE N'%%[_]db' ORDER BY sd.[name];" 

FOR /F %%B IN ('SQLCMD -h -1 -S %MyServer% -E -Q %MyQuery%') DO (
    REM remove the "echo" from the next line to run the scripts 
    echo SQLCMD -S %MyServer% -E -i %MyScript% -d %%B -o results-%%B.txt 
) 

Использование %%B в выходном файле даст вам другой выходной файл для каждой базы данных, например:

результаты database1_db.txt
результаты database2_db.txt
...


Другие ноты:

  • Использование (local) вместо localhost при подключении к локальной, например, по умолчанию, как он использует общую память, а localhost заставляет соединение TCP.

  • Если вы ищете подчеркивание в LIKE заявления, заключить его в квадратных скобках, иначе это является односимвольным джокером (который до сих пор технически работает иногда, но может также соответствовать другим символам): [_]

+0

@ user1588449 Ну, это не вопрос, который вы задали. Динамическое обнаружение баз данных, которые нужно запустить, сильно отличается от статического списка.Это необходимо упомянуть в вопросе, поскольку он полностью отменяет ответ Филипа Де Вос, поскольку это невозможно в режиме SQLCMD. Я обновил свой ответ, указав, как это сделать с помощью динамического набора баз данных. –

1

Спасибо всем, кто разбил! Ниже кажется, что он может работать (на основе ответа @ srutzky в)

SQLCMD -S "локальный" -E -i "C: \ release.sql" -d Database1 -o results.txt

То, что мне не хватает с помощью командной строки cmd вместо SSMS, заключается в том, что я не думаю, что могу писать курсор для прокрутки каждой базы данных, которая заканчивается на «_db», а затем выполняется против этого ... Вот SQL, у меня есть но мне просто нужно установить ссылку на файл SQL для выполнения.

link

Если я поставил скрипт SQL релиза в этот файл в @text переменной она не работает, потому что она взрывается на каждом GO заявления я имею в моем файле release.sql.

declare @text as nvarchar(max) 
set @text = N' 
-- GET AND RUN SCRIPT FROM DISK! 
' 

declare C_CURSOR CURSOR FOR 
    select [Name] from sys.databases 
    where name like '%_db' 
    order by name 

declare @runtext as nvarchar(max) 
declare @DB_Name as nvarchar(200) 

OPEN C_CURSOR 
fetch next from C_CURSOR INTO @DB_Name 
WHILE(@@FETCH_STATUS = 0) 
BEGIN 

    print @DB_Name 
    set @runtext = 'select ''' + @DB_Name + ''' as DatabaseName 
     use ' + @DB_Name + N' 
    ' + @text 

    exec sp_executesql @runtext 

    fetch next from C_CURSOR INTO @DB_Name 
END 

CLOSE C_CURSOR 
DEALLOCATE C_CURSOR 

Еще раз спасибо!

+0

Пожалуйста, разместите это как дополнение к вопросу. Это не ответ; это более подробно на вопрос. Он должен быть помещен туда, и этот ответ следует удалить. –

0

В итоге я объединил 2 вещи. Я создал SQL-скрипт, который создает курсор для поиска баз данных, а затем распечатывает список команд для приглашения CMD. Затем я запустил это в командной строке. Ниже мы выводим наш SQL-скрипт, а затем сохраняем его как файл .bat, который мы запускаем. Он отлично работает!

Этот сценарий, по существу, создается с помощью следующего сценария SQL:

/*** GET DATABASES IN THE CURSOR QUERY BELOW! */ 
declare C_CURSOR CURSOR FOR 
     select [Name] from sys.databases 
     where name like '%_db' 
     order by name 

/* THIS IS WHERE THE CURSOR STARTS*/ 
declare @DB_Name as nvarchar(200) 

OPEN C_CURSOR 
fetch next from C_CURSOR INTO @DB_Name 
WHILE(@@FETCH_STATUS = 0) 
BEGIN 

    print 'SQLCMD -S "localhost" -E -i "C:\release.sql" -d ' + @DB_Name + ' -o ' + @DB_Name + '_results.txt' 

    fetch next from C_CURSOR INTO @DB_Name 
END 

CLOSE C_CURSOR 
DEALLOCATE C_CURSOR 

Это выводит следующее который мы затем запустить в .bat файле

SQLCMD -S "localhost" -E -i "C:\release.sql" -d database1 -o database1_results.txt 
SQLCMD -S "localhost" -E -i "C:\release.sql" -d database2 -o database2_results.txt 
SQLCMD -S "localhost" -E -i "C:\release.sql" -d database3 -o database3_results.txt 

Спасибо всем!

+0

Зачем вам это делать? ... это 3 шага, 2 из которых требуют ручного исполнения, по сравнению с 1 шагом, который я предложил, можно полностью автоматизировать. .. Какая польза от этого метода? .. вы видите мой обновленный ответ? Я объясню, почему вы должны использовать '(local)' вместо 'localhost'. –

Смежные вопросы