TSQL可配置的数据库名称

时间:2017-07-10 12:19:07

标签: sql sql-server tsql

我正在尝试使我的数据库名称可配置为能够运行这样的内容:

declare @x nvarchar(MAX)
declare @y nvarchar(MAX)

set @x = 'database1'
set @y = 'database2'

select * from @x.table1 INNER JOIN @y.table2 ON ....  

有没有办法在SQL Server 2016上实现它? 非常感谢。

3 个答案:

答案 0 :(得分:5)

一种方法是使用SQLCMD变量:

:SETVAR x "database1"
:SETVAR y "database2"

SELECT * FROM $(x).dbo.table1 INNER JOIN $(y).dbo.table2 ON ....  

要在SSMS中运行SQLCMD脚本,请从“查询”菜单中启用SQLCMD模式。

如果使用SQLCMD实用程序从命令行运行脚本,则可以省略SETVAR命令并将值作为命令行参数传递。

答案 1 :(得分:2)

您无法在SQL中参数化标识符 您唯一的选择是使用动态SQL。 (顺便说一句,您的代码示例表明您正在讨论的是表,而不是数据库)

declare @x sysname, @sysname, @sql nvarchar(max)

SELECT @x = 'table1', 
       @y = 'table2'

SET @SQL = 'SELECT * FROM '+ @x +' INNER JOIN '+ @y +' ON ....'

EXEC(@SQL)

但是,由于这是动态SQL,因此您正在为SQL注入攻击打开一扇门。 还有两件事要做,以保护自己:

  1. 使用quotename
  2. 确保您的数据库中确实包含这些表格
  3. 所以更好的代码就是这样:

    declare @x sysname, @sysname, @sql nvarchar(max)
    
    SELECT @x = 'table1', 
           @y = 'table2'
    
    IF 
    (
        SELECT COUNT(*)
        FROM InformationSchema.Tables
        WHERE TABLE_NAME IN(@x, @y)
    ) = 2 
    BEGIN
        SET @SQL = 'SELECT * FROM quotename('+ @x +') INNER JOIN quotename('+ @y +') ON ....'
    
        EXEC(@SQL)
    END
    

答案 2 :(得分:0)

使用SYNONYMs

create SYNONYM YourTableReference FOR YourDatabaseName.dbo.YourTable;

create SYNONYM YourTableRefernce2 FOR YourDatabaseNameNumber2.dbo.YourTable;

select * from YourTableReference r
inner join YourTableRefernce2 r2 on r.Id=r2.Id -- etc . . . .