能否从SQL查询中执行文本文件?

41

我有一些生成的.sql文件,想要按顺序运行它们。我希望可以通过查询语句(如Query Analyzer/Server Management Studio)来运行它们。
是否可能实现这样的目标,如果是,语法是什么?

我希望可以使用类似以下的方式:

exec 'c:\temp\file01.sql' 
exec 'c:\temp\file02.sql'

我正在使用SQL Server 2005,并在管理工具中运行查询。

9个回答

49

使用xp_cmdshellsqlcmd

EXEC xp_cmdshell  'sqlcmd -S ' + @DBServerName + ' -d  ' + @DBName + ' -i ' + @FilePathName

1
这个能在 SQL Azure 上执行吗? - Ahmed Elbatt

20
非常有帮助,谢谢。同样请参考此链接:执行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 

关闭

EXEC master.dbo.sp_configure 'xp_cmdshell', 0 
RECONFIGURE 
EXEC master.dbo.sp_configure 'show advanced options', 0 
RECONFIGURE  
SET NOCOUNT OFF 

10
或者使用openrowset将您的脚本读入变量并执行它(很抱歉重新启动了一个8年前的话题):
DECLARE @SQL varchar(MAX)
SELECT @SQL = BulkColumn
FROM OPENROWSET
    (   BULK 'MeinPfad\MeinSkript.sql'
    ,   SINGLE_BLOB ) AS MYTABLE

--PRINT @sql
EXEC (@sql)

6

这是我使用的方法。它很有效,而且简单易用。可以将其更改为读取目录中的所有文件,但这样我就可以控制要执行哪些文件。

/*  
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  

好的解决方案,我还结合了Archi Moore的答案来启用和禁用xp_cmdshell功能。 - Trevor

5

我不建议这样做,但如果你确实需要的话,可以使用扩展存储过程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在后台运行命令,因此不应用于运行需要用户输入的程序。


3

对于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替换为您的服务器名称。


3
请看OSQL。这个工具允许您从命令提示符运行SQL。它很容易安装在系统上,我认为它与免费的SQL Server Express一起提供。
使用osql实用程序的详细信息,请参见此处
在stackoverflow上快速搜索“OSQL”可以找到大量相关内容。
正确处理传递到命令行的用户和密码参数是最重要的部分。我见过使用NT文件访问权限来控制带密码的文件,并使用此文件的内容启动脚本的批处理文件。您还可以编写快速的C#或VB程序,使用Process类运行它。

2
我不知道快速搜索显示了什么,但是自从 SQL Server 2005 开始,OSQL 已经被弃用,取而代之的是 SQLCMD。即使在安装了 SQL Server 2005 的机器上运行 OSQL,也会显示:“注意:osql 不支持 SQL Server 2005 的所有功能。请改用 sqlcmd。有关详细信息,请参见 SQL Server Books Online。” - Gennady Vanin Геннадий Ванин

2

打开Windows命令行(CMD)

sqlcmd -S localhost -d NorthWind -i "C:\MyScript.sql"

这对我奏效了,我只需要将“localhost”更新为我们的SQL Server地址,“NorthWind”更新为数据库名称。这两个文本字符串在SSMS中都很容易找到。谢谢! - Igor

2
对于像我一样偶然发现这个问题并可能会发现这个有用的人,我喜欢Bruce Thompson的答案(它从循环中的文件运行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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接