我有这个 MSSQL SQLCMD 代码,它可以登录数据库,并在其中执行 SELECT 语句:
:CONNECT czasql-001
SELECT * FROM [Lps_Hepper_Cz].[config].[LpsPlant]
GO
:CONNECT LS_Hepper_DK
SELECT * FROM [LPS_Hepper_NY].[config].[LpsPlant]
:CONNECT LS_Hepper_DK
SELECT * FROM [LPS_Hepper_DK].[config].[LpsPlant]
:CONNECT LS_Hepper_DK
SELECT * FROM [LPS_Hepper_SUPPLIER].[config].[LpsPlant]
GO
:CONNECT LS_Hepper_372
SELECT * FROM [LPS_Hepper_MO].[config].[LpsPlant]
GO
:CONNECT LS_Hepper_678
SELECT * FROM [LPS_Hepper_678].[config].[LpsPlant]
GO
此解决方案工作正常,但需要我多次复制粘贴副本才能更改数据库名称。但是有人可以通过使用循环来帮助我改进这一点吗?我尝试过使用临时表。就像这样:
declare @tbl table (ServerName nvarchar(50), DbName nvarchar(50), IsDone bit default(0))
insert into @tbl (ServerName,DbName) VALUES ('CZASQL-001', '[Lps_Hepper_CZ]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_DK]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_NY]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_Supplier]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_372', '[Lps_Hepper_MO]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_678', '[Lps_Hepper_678]')
但是当我拥有的数据为 nvarchar 时,我无法弄清楚如何执行迭代数据库、连接到服务器并设置数据库名称的逻辑? 有人有建议吗?
更新: 我只会将其用于插入/更新或删除。所以我不使用存储过程。我喜欢用它来更新我们所有数据库上的数据。这就是为什么我只使用临时表,它应该是脚本的一部分。
服务器名称和数据库名称将来自上面的临时表。所有数据库的表名称都相同,因为我们在全局范围内都有数据库副本以限制数据下载,所以我需要确保当我更新一个数据库时,我也会更新其余的数据库。
更新 2: 我尝试使用它,但我一直停滞不前,无法使用临时表中的值。这意味着我无法使用 :SETVAR 来设置服务器名称:
declare @tbl table (ServerName nvarchar(50), DbName nvarchar(50), IsDone bit default(0))
insert into @tbl (ServerName,DbName) VALUES ('CZASQL-001', '[Lps_Hepper_CZ]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_DK]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_NY]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_DK', '[Lps_Hepper_Supplier]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_372', '[Lps_Hepper_MO]')
insert into @tbl (ServerName,DbName) VALUES ('LS_Hepper_678', '[Lps_Hepper_678]')
WHILE (SELECT COUNT(*) FROM @tbl WHERE IsDone = 0) > 0
BEGIN
DECLARE @selectedRow INT = (SELECT TOP 1 Id FROM @tbl WHERE IsDone = 0)
--DECLARE @ServerName NVARCHAR(50)= (SELECT ServerName FROM @tbl WHERE Id = @selectedRow)
--DECLARE @DatabaseName NVARCHAR(50) = (SELECT DbName FROM @tbl WHERE Id = @selectedRow)
DECLARE @ServerName sysname= (SELECT ServerName FROM @tbl WHERE Id = @selectedRow)
DECLARE @DatabaseName sysname = (SELECT DbName FROM @tbl WHERE Id = @selectedRow)
:SETVAR DatabaseName @DatabaseName
:SETVAR ServerName @ServerName
SELECT ServerName --This looks correctly
print CONVERT(NVARCHAR(100),@selectedRow)
:CONNECT ServerName
USE @DatabaseName
GO
SELECT * FROM [config].[LpsPlant]
GO
UPDATE @tbl SET IsDone = 1 WHERE Id = @selectedRow
END;
最佳答案
I'm only going to use this for INSERT/UPDATE or DELETE. So im not using a stored procedure. I like to use this for updating data on all our databases
如果是这种情况,您可以考虑使用 Registered Servers
:
Benefits of Registered Servers
With Registered Servers you can:
Register servers to preserve the connection information.
Determine if a registered server is running.
Easily connect Object Explorer and Query Editor to a registered server.
Edit or delete the registration information for a registered server.
Create groups of servers.
Provide user-friendly names for registered servers by providing a value in the Registered server name box that is different from the Server name list.
Provide detailed descriptions for registered servers.
Provide detailed descriptions of registered server groups.
Export registered server groups.
Import registered server groups.
View the SQL Server log files for online or offline instances of SQL Server
- Execute Statements Against Multiple Servers Simultaneously
您可以基于服务器/数据库/环境(DEV/PROD/QA)创建多个组。
另一种可能性是将注册的服务器导出到文件,放入源代码控制系统(SVN/Git)并与其他开发人员共享。
使用 SSMS,您可以根据服务器组单击新查询,并同时在多个数据库上执行相同的查询。
关于sql - 通过动态调用使用 SQLCMD 的更智能方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36918741/