使用SQLCMD进行动态调用的更智能方式

mor*_*rck 11 sql sql-server sqlcmd

我有这个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
Run Code Online (Sandbox Code Playgroud)

此解决方案可以正常工作,但要求我多次复制粘贴副本以更改数据库名称.但是有人可以通过使用循环来帮助我改进这一点.我试过使用临时表.像这样:

 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]')
Run Code Online (Sandbox Code Playgroud)

但我不知道要做的迭代通过数据库连接到服务器和设置数据库名称的逻辑,当我的数据是一个nvarchar?有人有建议吗?

更新: 我只会将其用于INSERT/UPDATE或DELETE.所以我不使用存储过程.我喜欢用它来更新我们所有数据库的数据.这就是为什么我只使用临时表,它应该是脚本的一部分.

Servernames和数据库名称将来自上面的临时表.表名在所有数据库上是相同的,因为我们在全球范围内拥有数据库副本以限制数据下载,我需要确保在更新时,我还会更新其余数据库.

更新2: 我试图玩它,但我一直停滞不前,因为无法使用临时表中的值.意思是我不能使用:SETVAR来设置servername:

  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;
Run Code Online (Sandbox Code Playgroud)

Luk*_*zda 1

我只会将其用于插入/更新或删除。所以我不使用存储过程。我喜欢用它来更新我们所有数据库上的数据

如果是这种情况,您可以考虑使用Registered Servers

注册服务器的好处

通过注册服务器,您可以:

  • 注册服务器以保留连接信息。

  • 确定已注册的服务器是否正在运行。

  • 轻松将对象资源管理器和查询编辑器连接到已注册的服务器。

  • 编辑或删除已注册服务器的注册信息。

  • 创建服务器组。

  • 通过在“注册服务器名称”框中提供与“服务器名称”列表不同的值,为注册服务器提供用户友好的名称。

  • 提供注册服务器的详细描述。

  • 提供已注册服务器组的详细描述。

  • 导出已注册的服务器组。

  • 导入已注册的服务器组。

  • 查看 SQL Server 联机或脱机实例的 SQL Server 日志文件

  • 同时针对多个服务器执行语句

您可以基于服务器/数据库/环境(DEV/PROD/QA)创建多个组。

另一种可能性是将注册的服务器导出到文件,放入源代码控制系统(SVN/Git)并与其他开发人员共享。

使用 SSMS,您可以根据服务器组单击新查询,并同时在多个数据库上执行相同的查询。

在此输入图像描述

图片来自:http://sqlmag.com/site-files/sqlmag.com/files/archive/sqlmag.com/content/content/142469/Greenwood-SQL2331-Fig5-sm.jpg