在引用链接服务器中的表的本地数据库中创建存储过程

edw*_*ins 6 sql-server stored-procedures linked-server

我目前有一个本地服务器链接到远程服务器。

是否可以在本地服务器内创建存储过程,但从链接服务器内的表中查询数据。我知道可能存在性能问题,但我不愿意在链接服务器上创建 sp,因为它需要获得权限才能这样做。

我相信我的问题是语法,但我无法确定到底是什么,

USE [LOCALDB]  --my local database or should I reference linked server db here
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROC [dbo].[mystoredprocedure]
    DECLARE @linkedserv NVARCHAR(150)
    DECLARE @linkeddb NVARCHAR(150)

    SET @linkedserv = 'HOSTNAME\SERVER';
    SET @linkeddb = 'remotedb';

    SELECT (CASE LTRIM(RTRIM([COLUMN1]))
        WHEN '' Then ''
        WHEN 'THIS' THEN 'THAT'
        WHEN 'NOW' THEN 'NEVER'
        ELSE 'OTHER' END) [Options]
    INTO #TempTable
    FROM @linkedserv.@linkeddb.dbo.TableOnLinkedServer --is this an issue?
    FULL OUTER JOIN OtherTableOnLinkedServer ON TableOnLinkedServer.COUMN1 = 
    OtherTableOnLinkedServer.COLUMN0   
Run Code Online (Sandbox Code Playgroud)

链接服务器 db 及其表在整个 sp 中被多次查询,因此找到引用它们的速记方式会很棒,

干杯

Aar*_*and 8

您不能将实体名称参数化为 T-SQL 语句。为此,您需要 (a) 首先创建 #temp 表,以及 (b) 使用动态 SQL。这是一种方法:

CREATE PROCEDURE [dbo].[mystoredprocedure]
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @exec nvarchar(256),
    @linkedserv nvarchar(150),
    @linkeddb   nvarchar(150),
    @sql        nvarchar(max);

  SELECT @linkedserv = N'HOSTNAME\SERVER',
         @linkeddb   = N'remotedb';

  SELECT @exec = QUOTENAME(@linkedserv) + N'.'
               + QUOTENAME(@linkeddb) + N'.sys.sp_executesql';

  CREATE TABLE #TempTable([Options] varchar(64));

  SELECT @sql = N'SELECT (CASE LTRIM(RTRIM(ot.[COLUMN1]))
        WHEN ''''     THEN ''''
        WHEN ''THIS'' THEN ''THAT''
        WHEN ''NOW''  THEN ''NEVER''
        ELSE ''OTHER'' END) AS [Options]
    FROM dbo.TableOnLinkedServer AS t
    FULL OUTER JOIN dbo.OtherTableOnLinkedServer AS ot
      ON t.COLUMN1 = ot.COLUMN0;';

  INSERT #TempTable([Options]) EXEC @exec @sql;   

  SELECT * FROM #TempTable;
END
GO
Run Code Online (Sandbox Code Playgroud)

您可以在动态 SQL 中完成所有操作,因此如果预先了解列是一项挑战,那么有一种方法。但它很混乱,假设您实际上需要一个#temp 表,因为这样您所做的一切都#TempTable必须在动态 SQL 中完成。

CREATE PROCEDURE [dbo].[mystoredprocedure]
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @exec nvarchar(256),
    @linkedserv nvarchar(150),
    @linkeddb   nvarchar(150),
    @sql        nvarchar(max);

  SELECT @linkedserv = N'HOSTNAME\SERVER',
         @linkeddb   = N'remotedb';

  SELECT @exec = QUOTENAME(@linkedserv) + N'.'
               + QUOTENAME(@linkeddb) + N'.sys.sp_executesql';

  SELECT @sql = N'SELECT (CASE LTRIM(RTRIM(ot.[COLUMN1]))
        WHEN ''''     THEN ''''
        WHEN ''THIS'' THEN ''THAT''
        WHEN ''NOW''  THEN ''NEVER''
        ELSE ''OTHER'' END) AS [Options]
    INTO #TempTable
    FROM dbo.TableOnLinkedServer AS t
    FULL OUTER JOIN dbo.OtherTableOnLinkedServer AS ot
      ON t.COLUMN1 = ot.COLUMN0;

  SELECT * FROM #TempTable;';

  EXEC @exec @sql;   
END
GO
Run Code Online (Sandbox Code Playgroud)

请查看有关动态 T-SQL 的Erland Sommarskog 必填文章,以确保您最终不会创建令人尴尬的 SQL 注入漏洞。