我有一个SQL脚本,我需要在大约20个不同的数据库上运行。
我基本上只需要能够运行一些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
- 等...
我已经在网上看了一堆,找到了一种在sqlcmd的批处理文件中做类似事情的方法,但是它没有工作,我也不知道如何以这种方式切换数据库,要么
非常感谢!
本
答案 0 :(得分:5)
您可以将management studio切换到sqlcmd模式(查询菜单),然后使用:r script.sql
要在动态生成的数据库列表中执行此操作,您必须执行一些sqlcmd技巧:
我假设在这个例子中,c:\temp
中存在script.sql文件。请注意,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
答案 1 :(得分: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
语句中搜索下划线,请将其括在方括号中,否则它是单字符外卡(有时在技术上仍有效,但也可以与其他字符匹配) :[_]
答案 2 :(得分:1)
谢谢大家投入!以下似乎可能有效(基于@ srutzky的回答)
sqlcmd -S" localhost" -E -i" c:\ release.sql" -d database1 -o results.txt
我使用cmd提示而不是SSMS而遗漏的是,我不认为我可以编写游标来循环遍历以" _db"结尾的每个数据库。然后对此执行...这是我的SQL,但我只需要能够将链接放到要执行的SQL文件中。
如果我将发布脚本SQL放入@text变量中,它就不起作用,因为它会破坏我在release.sql文件中的每个GO语句。
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
再次感谢!
答案 3 :(得分:0)
我最终结合了两件事。我创建了一个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
谢谢大家!