我在同一台服务器上有多个数据库 (SqlServer 2005),它们具有相同的模式但数据不同。
我有一个额外的数据库,其中有一张表存储上述数据库的名称。
所以我需要做的是遍历这些数据库名称并实际“切换”到每个数据库(使用 [dbname])并执行 T-SQL 脚本。我清楚了吗?
我举个例子(从真实的例子中简化而来):
CREATE TABLE DatabaseNames
(
Id int,
Name varchar(50)
)
INSERT INTO DatabaseNames SELECT 'DatabaseA'
INSERT INTO DatabaseNames SELECT 'DatabaseB'
INSERT INTO DatabaseNames SELECT 'DatabaseC'
假设DatabaseA、DatabaseB、DatabaseC是真实存在的数据库。 所以假设我需要在这些数据库上创建一个新的 SP。我需要一些脚本来遍历这些数据库并执行我指定的 T-SQL 脚本(可能存储在 varchar 变量或任何地方)。
有什么想法吗?
最佳答案
最简单的方法是这样的:
DECLARE @stmt nvarchar(200)
DECLARE c CURSOR LOCAL FORWARD_ONLY FOR SELECT 'USE [' + Name + ']' FROM DatabaseNames
OPEN c
WHILE 1 <> 0 BEGIN
FETCH c INTO @stmt
IF @@fetch_status <> 0 BREAK
SET @stmt = @stmt + ' ' + @what_you_want_to_do
EXEC(@stmt)
END
CLOSE c
DEALLOCATE c
但是,显然它不适用于需要成为批处理中第一个语句的语句,例如 CREATE PROCEDURE。为此,您可以使用 SQLCLR。创建和部署这样的类:
public class StoredProcedures {
[SqlProcedure(Name="exec_in_db")]
public static void ExecInDb(string dbname, string sql) {
using (SqlConnection conn = new SqlConnection("context connection=true")) {
conn.Open();
using (SqlCommand cmd = conn.CreateCommand()) {
cmd.CommandText = "USE [" + dbname + "]";
cmd.ExecuteNonQuery();
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
}
}
}
然后你可以做
DECLARE @db_name nvarchar(200)
DECLARE c CURSOR LOCAL FORWARD_ONLY FOR SELECT Name FROM DatabaseNames
OPEN c
WHILE 1 <> 0 BEGIN
FETCH c INTO @@db_name
IF @@fetch_status <> 0 BREAK
EXEC exec_in_db @db_name, @what_you_want_to_do
END
CLOSE c
DEALLOCATE c
关于sql-server-2005 - 如何对名称存储在表中的多个数据库执行 T-SQL?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2465102/