我有一个sql server存储过程,用于在升级之前从我们的数据库备份数据,我真的希望它能够通过传入数据库名称来运行多个数据库上的存储过程参数。是否有捷径可寻?我能想到的最好的方法是在存储过程中动态构建sql,但感觉这是错误的方法。
答案 0 :(得分:2)
构建一个备份当前数据库的过程,无论它是什么。在要备份的所有数据库上安装此过程。
编写另一个将启动备份的过程。这将取决于您未提及的内容,例如,如果您有一个表,其中包含要备份的每个数据库的名称或类似的内容。基本上你需要做的就是遍历数据库名称并构建一个字符串,如:
SET @ProcessQueryString=
'EXEC '+DatabaseServer+'.'+DatabaseName+'.dbo.'+'BackupProcedureName param1, param2'
然后只是:
EXEC (@ProcessQueryString)
远程运行。
答案 1 :(得分:1)
没有任何其他方法可以做到这一点。动态SQL是唯一的方法;如果您对DB名称进行严格控制以及谁在运行它,那么您可以将所有内容一起截断,但如果有任何疑问,请使用QUOTENAME安全地转义参数:
CREATE PROCEDURE doStuff
@dbName NVARCHAR(50)
AS
DECLARE @sql NVARCHAR(1000)
SET @sql = 'SELECT stuff FROM ' + QUOTENAME(@dbName) + '..TableName WHERE stuff = otherstuff'
EXEC sp_ExecuteSQL (@sql)
显然,如果还有更多内容被传递,那么您将需要仔细检查任何其他输入,并可能使用参数化动态SQL,例如:
CREATE PROCEDURE doStuff
@dbName NVARCHAR(50)
@someValue NVARCHAR(10)
AS
DECLARE @sql NVARCHAR(1000)
SET @sql = 'SELECT stuff FROM ' + QUOTENAME(@dbName) + '..TableName WHERE stuff = @pOtherStuff'
EXEC sp_ExecuteSQL (@sql, '@pOtherStuff NVARCHAR(10)', @someValue)
然后确保动态SQL的参数安全地传递,并减少注入攻击的可能性。它还可以提高与查询关联的执行计划重用的可能性。
答案 2 :(得分:0)
就个人而言,我只是使用批处理文件和shell来sqlcmd这样的事情。否则,在存储过程中构建sql(就像你说的那样)可以正常工作。不知道为什么这样做会“错误”。
最好的问候, 别
答案 3 :(得分:0)
MSSQL有一个OPENQUERY(dbname,statement)函数,如果服务器已链接,则将其指定为第一个参数,并触发该服务器的语句。
你可以在动态proc中生成这个openquery语句。并且它可以在每个服务器上触发备份过程,也可以直接执行该语句。
您使用SSIS吗?如果是这样,您可以尝试创建几个ssis包并尝试安排它们,或远程执行它们。