Sql-Server

在本地數據庫中創建引用連結伺服器中的表的儲存過程

  • May 7, 2019

我目前有一個連結到遠端伺服器的本地伺服器。

是否可以在本地伺服器中創建儲存過程,但從連結伺服器中的表中查詢數據。我知道可能存在性能問題,但我不願意在連結伺服器上創建 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   

連結伺服器 db 及其表在整個 sp 中被多次查詢,因此找到一種引用它們的速記方式會很棒,

乾杯

您不能將實體名稱參數化為 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

您可以在動態 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

請查看有關動態 T-SQL的 Erland Sommarskog 強制性文章,以確保您最終不會創建令人尷尬的 SQL 注入漏洞。

引用自:https://dba.stackexchange.com/questions/237562