J'ai actuellement un serveur local lié à un serveur distant.
Est-il possible de créer une procédure stockée dans le serveur local, mais en interrogeant les données des tables dans le serveur lié. Je suis conscient qu'il peut y avoir des problèmes de performances, mais je suis réticent à créer le sp sur le serveur lié car cela nécessiterait d'obtenir des autorisations pour le faire.
Je crois que mon problème est la syntaxe mais je ne peux pas identifier exactement quoi,
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 @[email protected] --is this an issue?
FULL OUTER JOIN OtherTableOnLinkedServer ON TableOnLinkedServer.COUMN1 =
OtherTableOnLinkedServer.COLUMN0
Les serveurs liés db et ses tables sont interrogés à plusieurs reprises tout au long du sp. Il serait donc très utile de trouver un raccourci pour les référencer,
À votre santé
Vous ne pouvez pas paramétrer les noms d'entité dans une instruction T-SQL. Pour ce faire, vous devez (a) créer d'abord la table #temp, et (b) utiliser le SQL dynamique. Voici une approche:
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
Vous pouvez le faire tout à l'intérieur de SQL dynamique, donc si connaître les colonnes à l'avance est un défi, il existe un moyen. Mais c'est compliqué, en supposant que vous ayez réellement besoin d'une table #temp, car alors tout ce que vous faites avec #TempTable
doit être fait à l'intérieur du SQL dynamique.
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
Veuillez consulter l'article obligatoire d'Erland Sommarskog sur T-SQL dynamique pour vous assurer de ne pas finir par créer une vulnérabilité embarrassante à l'injection SQL.