SQL Server链接服务器加入

Its*_*eus 3 sql sql-server sql-server-2008

我在我的sql server 2008中添加了一个链接服务器.我想从一个表和一个驻留在我的链接服务器上的表值函数中获取数据,并按照下面给出的命名约定将这些数据连接到本地表.

<server>.<database>.<schema>.<table>
Run Code Online (Sandbox Code Playgroud)

但是我的第一个问题是我需要<server>从表中获取部分.因此,当我尝试做类似跟随它的事情失败时

Select * FROM @ServerNameVariable.database.dbo.myTable
Run Code Online (Sandbox Code Playgroud)

知道如何用用户定义的变量形成完全限定的链接服务器表名?

我的SP如下

CREATE PROCEDURE TEST_SP    
AS
BEGIN
    DECLARE @NetworkDBName VARCHAR(255) 
    SET @NetworkDBName = '[MyLinkedServerName]'
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here 
    select * from @NetworkDBName + '.' + testDatabase.dbo.Invoice_tb
END
GO
Run Code Online (Sandbox Code Playgroud)

des*_*ata 6

您不能使用变量代替数据库,模式或表名.

相反,您可以使用sp_ExecuteSQL构建和执行动态SQL语句.

此示例不起作用,因为服务器名称被视为字符串而不是服务器对象.

失败的例子

/* Anti-pattern.
 * Does not work.
 */
DECLARE @Server    SYSNAME = 'Server001';

SELECT
    *
FROM
    @Server.Database1.dbo.Table1
;
Run Code Online (Sandbox Code Playgroud)

此示例显示了一个可行的方法.这里,SQL语句构建为一个字符串,然后执行.

/* Dynamic SQL statement.
 * Will work.
 */
DECLARE @Server    SYSNAME = 'Server001';
DECLARE @Statement    NVARCHAR(255);

SET @Statement = 'SELECT * FROM ' + QUOTENAME(@Server) + '.Database1.dbo.Table1;';

EXECUTE sp_ExecuteSQL @Statement;
Run Code Online (Sandbox Code Playgroud)

如初; 生成和执行动态SQL语句时请小心.您不希望自己打开SQL注入攻击.在执行之前,查看OPENROWSET或检查传递的服务器名称是否符合上面@Devart提供的代码(SELECT name FROM sys.servers WHERE server_id> 0).

编辑1:在SQL注入的段落中添加了更多细节.

编辑2:删除第二个示例查询中的方括号,替换为QUOTENAME,根据@TTs注释.

  • 而不是用矩形括号手动括起服务器名称(或数据库,表名等),使用[`QUOTENAME函数`](https://msdn.microsoft.com/nl-be/library/ms176114.aspx).如果名称包含矩形括号,此函数将正确转义. (2认同)