Ответ 1
используйте xp_cmdshell и sqlcmd
EXEC xp_cmdshell 'sqlcmd -S ' + @DBServerName + ' -d ' + @DBName + ' -i ' + @FilePathName
У меня есть несколько сгенерированных файлов .sql, которые я хочу запустить последовательно. Я хотел бы запустить их из инструкции SQL в запросе (т.е. Query Analyzer/Server Management Studio).
Можно ли сделать что-то подобное, и если да, то в чем синтаксис для этого?
Я надеюсь на что-то вроде:
exec 'c:\temp\file01.sql'
exec 'c:\temp\file02.sql'
Я использую SQL Server 2005 и запускаю запросы в студии управления.
используйте xp_cmdshell и sqlcmd
EXEC xp_cmdshell 'sqlcmd -S ' + @DBServerName + ' -d ' + @DBName + ' -i ' + @FilePathName
Очень полезно поблагодарить, см. также эту ссылку:
Выполнять сценарии SQL Server
для аналогичного примера.
Чтобы включить и выключить xp_cmdshell
, см. Ниже:
О
SET NOCOUNT ON
EXEC master.dbo.sp_configure 'show advanced options', 1
RECONFIGURE
EXEC master.dbo.sp_configure 'xp_cmdshell', 1
RECONFIGURE
Off
EXEC master.dbo.sp_configure 'xp_cmdshell', 0
RECONFIGURE
EXEC master.dbo.sp_configure 'show advanced options', 0
RECONFIGURE
SET NOCOUNT OFF
Это то, что я использую. Хорошо работает и просто повторное использование. Его можно изменить, чтобы прочитать все файлы в каталоге, но таким образом я могу контролировать, какие из них выполнять.
/*
execute a list of .sql files against the server and DB specified
*/
SET NOCOUNT ON
SET XACT_ABORT ON
BEGIN TRAN
DECLARE @DBServerName VARCHAR(100) = 'servername'
DECLARE @DBName VARCHAR(100) = 'db name'
DECLARE @FilePath VARCHAR(200) = 'path to scrips\'
/*
create a holder for all filenames to be executed
*/
DECLARE @FileList TABLE (Files NVARCHAR(MAX))
INSERT INTO @FileList VALUES ('script 1.sql')
INSERT INTO @FileList VALUES ('script 2.sql')
INSERT INTO @FileList VALUES ('script X.sql')
WHILE (SELECT COUNT(Files) FROM @FileList) > 0
BEGIN
/*
execute each file one at a time
*/
DECLARE @FileName NVARCHAR(MAX) = (SELECT TOP(1) Files FROM @FileList)
DECLARE @command VARCHAR(500) = 'sqlcmd -S ' + @DBServerName + ' -d ' + @DBName + ' -i "' + @FilePath + @Filename +'"'
EXEC xp_cmdshell @command
PRINT 'EXECUTED: ' + @FileName
DELETE FROM @FileList WHERE Files = @FileName
END
COMMIT TRAN
Или просто используйте openrowset, чтобы прочитать ваш script в переменной и выполнить его (извините за возрождение темы 8 лет):
DECLARE @SQL varchar(MAX)
SELECT @SQL = BulkColumn
FROM OPENROWSET
( BULK 'MeinPfad\MeinSkript.sql'
, SINGLE_BLOB ) AS MYTABLE
--PRINT @sql
EXEC (@sql)
Я бы не рекомендовал делать это, но если вам действительно нужно, тогда вам нужна расширенная хранимая процедура xp_cmdshell
. Сначала вам нужно будет прочитать содержимое файла в переменную, а затем использовать что-то вроде этого:
DECLARE @cmd sysname, @var sysname
SET @var = 'Hello world'
SET @cmd = 'echo ' + @var + ' > var_out.txt'
EXEC master..xp_cmdshell @cmd
Примечание. xp_cmdshell запускает команды в фоновом режиме, поэтому его нельзя использовать для запуска программ, требующих пользовательского ввода.
Взгляните на OSQL. Эта утилита позволяет запускать SQL из командной строки. Легко установить в систему, я думаю, что он поставляется с бесплатным SQL Server Express.
Быстрый поиск "OSQL" при переполнении стека показывает, что доступно много материала.
Главное, что нужно правильно обрабатывать, - это параметры учетной записи пользователя и пароля, которые передаются в командной строке. Я видел пакетные файлы, которые используют разрешения доступа к файлу NT для управления файлом с паролем, а затем с использованием этого содержимого файла для запуска script. Вы также можете написать быструю программу С# или VB для ее запуска с использованием класса Process.
Открыть командную строку Windows (CMD)
sqlcmd -S localhost -d NorthWind -i "C:\MyScript.sql"
Для проверки подлинности Windows, если вы работаете как другой пользователь: Откройте командную строку от имени пользователя Windows (щелкните правой кнопкой мыши по нему, выберите "Расположение файла", "Shift" + "Щелкните правой кнопкой мыши", "Запускать от имени другого пользователя")
sqlcmd -S localhost\SQLEXPRESS -d DatabaseName-i "c:\temp\script.sql"
Или, если вы используете Sql Server, пользователь:
sqlcmd -S localhost\SQLEXPRESS -d DatabaseName-i "c:\temp\script.sql" -U UserName -P Password
Замените localhost\SQLEXPRESS своим именем сервера, если не локальным сервером.
Любой, кто сталкивался с этим вопросом, как я, и мог бы найти это полезным, мне понравился ответ брюса Томпсона (который запускал SQL из файлов в цикле), но я предпочел подход Pesche Helfer к выполнению файлов (как избежать использования xp_cmdshell).
Таким образом, я объединил их (и немного подправил, чтобы все запускалось из папки, а не из списка, созданного вручную):
DECLARE @Dir NVARCHAR(512) = 'd:\SQLScriptsDirectory'
DECLARE @FileList TABLE (
subdirectory NVARCHAR(512),
depth int,
[file] bit
)
INSERT @FileList
EXEC Master.dbo.xp_DirTree @Dir,1,1
WHILE (SELECT COUNT(*) FROM @FileList) > 0
BEGIN
DECLARE @FileName NVARCHAR(MAX) = (SELECT TOP(1) subdirectory FROM @FileList)
DECLARE @FullPath NVARCHAR(MAX) = @Dir + '\' + @FileName
DECLARE @SQL NVARCHAR(MAX)
DECLARE @SQL_TO_EXEC NVARCHAR(MAX)
SELECT @SQL_TO_EXEC = 'select @SQL = BulkColumn
FROM OPENROWSET
( BULK ''' + @FullPath + '''
, SINGLE_BLOB ) AS MYTABLE'
DECLARE @parmsdeclare NVARCHAR(4000) = '@SQL varchar(max) OUTPUT'
EXEC sp_executesql @stmt = @SQL_TO_EXEC
, @params = @parmsdeclare
, @SQL = @SQL OUTPUT
EXEC (@sql)
DELETE FROM @FileList WHERE subdirectory = @FileName
PRINT 'EXECUTED: ' + @FileName
END