我知道我的帖子与这个论坛中的其他帖子非常相似,但我找不到我需要的答案。
这是我的问题,我在Windows Server上运行了一个SQL Server。在我的SQL Server中,我有大约30个数据库。它们都具有相同的表和相同的存储过程。
现在,问题是,我需要在所有这些数据库中运行这个庞大的脚本。我希望我只能对所有数据库进行一次。
我尝试了一些事情,比如去“查看”>>注册服务器>>本地服务器组>>新服务器注册。但是这个解决方案适用于许多服务器,而不是很多数据库。
我知道我可以通过输入数据库名称来实现,但查询真的很大,所以在所有数据库中运行都需要很长时间。
有没有人知道这是否可能?
答案 0 :(得分:7)
ApexSQL Propagate是可以在这种情况下提供帮助的工具。它用于在多个数据库,甚至多个服务器上执行单个或多个脚本。您应该做的只是选择该脚本,然后选择要对其执行该脚本的所有数据库:
加载脚本和数据库时,只需单击“执行”按钮并等待结果:
答案 1 :(得分:3)
考虑从SSMS(查询 - SQLCMD模式)运行SQLCMD Mode中的脚本。这样,您可以将脚本保存到文件中,并在每个所需数据库的上下文中轻松运行:
USE DB1;
:r C:\SqlScript\YourLargeScript.sql
GO
USE DB2;
:r C:\SqlScript\YourLargeScript.sql
GO
USE DB3;
:r C:\SqlScript\YourLargeScript.sql
GO
答案 2 :(得分:2)
您可以对所有数据库名称使用WHILE循环,并在EXECUTE内循环执行查询。我认为该语句SET @dbname = ...
可能会更好,但这也可以。
DECLARE @rn INT = 1, @dbname varchar(MAX) = '';
WHILE @dbname IS NOT NULL
BEGIN
SET @dbname = (SELECT name FROM (SELECT name, ROW_NUMBER() OVER (ORDER BY name) rn
FROM sys.databases WHERE name NOT IN('master','tempdb')) t WHERE rn = @rn);
IF @dbname <> '' AND @dbname IS NOT NULL
EXECUTE ('use ['+@dbname+'];
/* Your script code here */
UPDATE some_table SET ... ;
');
SET @rn = @rn + 1;
END;
答案 3 :(得分:1)
这是执行此操作的常规方法:
假设您要对数据库DBOther进行选择而不是:
select * from DBOther..TableName
同时检查表或视图是否在dbo架构上,如果不是,你也应该添加架构:请注意我现在只使用一个点数据库名称
select * from DBOther.dbo.ViewName
如果任何数据库位于另一台计算机上的另一台服务器上,请确保数据库位于链接服务器中 然后,您可以通过以下方式访问该数据库上的表或视图:
SELECT * FROM [AnotherServerName].[DB].[dbo].[Table]
以下是另一种不需要输入数据库名称的方法:
use DB1
go
select * from table1
go
use DB2
go
select * from table1
go
请注意,这仅适用于每个数据库上的表和字段完全相同的情况
答案 4 :(得分:1)
你可以写这样的剧本
DECLARE CURSOR_ALLDB_NAMES CURSOR FOR
SELECT name
FROM Sys.Databases
WHERE name NOT IN('master', 'tempdb')
OPEN CURSOR_ALLDB_NAMES
FETCH CURSOR_ALLDB_NAMES INTO @DB_NAME
WHILE @@Fetch_Status = 0
BEGIN
EXEC('UPDATE '+ @DB_NAME + '..SameTableNameAllDb SET Status=1')
FETCH CURSOR_ALLDB_NAMESINTO INTO @DB_NAME
END
CLOSE CURSOR_ALLDB_NAMES
答案 5 :(得分:0)
根据要求,您可以执行以下操作:
declare @dbName nvarchar(100)
declare @script nvarchar(max)
declare @dbIndex bigint = 0
declare @dbCount bigint = (
select count(*) from
sys.databases
)
declare crs_databases cursor for
(
select
[name]
from
sys.databases
)
open crs_databases
fetch next from crs_databases into @dbName
while @@FETCH_STATUS = 0
begin
set @dbIndex = @dbIndex+1
set @script = concat(@script,
' select Id from ['+@dbName+']..YourTableName ',
case
when @dbIndex = @dbCount then ''
else 'union'
end)
fetch next from crs_databases into @dbName
end
select @script
close crs_databases
deallocate crs_databases
请注意,双点符号表示架构为dbo。否则,您需要显式写下架构。
select Id from ['+@dbName+'].schema.YourTableName
当您需要在每台服务器上执行存储过程时,@script
变量将包含其他内容。
答案 6 :(得分:0)
您可以使用以下脚本在一组数据库上运行相同的脚本。只需在插入行中更改过滤器即可。
declare @dbs table (
dbName varchar(100),
done bit default 0
)
insert @dbs select [name], 0 FROM master.dbo.sysdatabases WHERE [Name] like 'targets_%'
while (exists(select 1 from @dbs where done = 0))
begin
declare @db varchar(100);
select top 1 @db = dbName from @dbs where done = 0;
exec ('
use [' + @db + '];
update table1 set
col1 = '''',
col2 = 1
where id = ''45b6facb-510d-422f-a48c-687449f08821''
');
print @db + ' updated!';
update @dbs set done = 1 where dbName = @db;
end
如果您的SQL Server版本不支持表变量,请使用临时表,但不要忘记在脚本末尾删除它们。
答案 7 :(得分:-1)