J'utilise deux serveurs local (SQL Server exécutant sur mon système) et à distance (SQL Server exécutant sur un autre système). J'ai créé des synonymes sur mon serveur local pour une table située sur le serveur distant.
Synonyme utilisé- CREATE SYNONYM [dbo].[test] FOR remoteserver_name .[database_name].[schema_name].object_name
exigence
J'ai besoin d'aller chercher les colonnes du synonyme.
Je peux récupérer les colonnes du synonyme à l'aide de la requête ci-dessous dans SQL Server.
select * from dbo.test
Où
dbo
est le nom de schéma de synonyme (nom de schéma de serveur local) et test
est nom de synonyme.
J'ai essayé de récupérer les colonnes des synonymes à l'aide de la requête ci-dessous, mais je ne peux pas récupérer les colonnes.
SELECT sys.schemas.name AS SCHEMA_NAME,
sys.synonyms.name AS view_name,
sys.columns.name AS COL_NAME,
sys.types.name AS data_typename
FROM sys.columns
INNER JOIN sys.synonyms
ON OBJECT_ID(sys.synonyms.base_object_name) = sys.columns.object_id
INNER JOIN sys.schemas
ON sys.schemas.schema_id = sys.synonyms.schema_id
LEFT OUTER JOIN sys.types
ON sys.columns.system_type_id = sys.types.system_type_id
WHERE sys.types.system_type_id = sys.types.user_type_id
AND sys.schemas.name = N'scehmaname'
AND sys.synonyms.name = N'synonymname'
Pouvez-vous suggérer une autre solution pour récupérer les colonnes du synonyme ou corriger la requête ci-dessus?
Votre erreur est que vous demandez à votre local Server sur l'objet à partir d'un autre, télécommande serveur.
OBJECT_ID(sys.synonyms.base_object_name)
à partir de votre code sera résolu sur un serveur local car OBJECT_ID()
fonctionne dans le serveur local, mais vous vous transmettez le nom du serveur distant, vous obtiendrez donc NULL
ici.
Si vous souhaitez obtenir l'objet de l'objet distant object_id
, Vous devriez faire de la smth comme ceci:
exec ('select object_id(''[remote_db].[remote_schema].[remote_table]'')') at [remote_server]
Et en général, si vous souhaitez obtenir les colonnes de l'objet distant, vous devez exécuter votre code sur le serveur remote
, à la recherche de colonnes de REMOTE objet dans le Remotesys.columns
Dans Télécommande Base de données, par exemple, de cette façon:
declare @obj_name sysname = '[remote_server].[remote_db].[remote_table]';
declare @code nvarchar(4000) =
N'select c.name AS COL_NAME,
t.name AS data_typename
from sys.columns c
join sys.types t
on c.system_type_id = t.system_type_id
where c.object_id = object_id(@obj_name)';
declare @param_def nvarchar(400) = N'@obj_name sysname';
execute [remote_server].[remote_db].dbo.sp_executesql @code, @param_def, @obj_name = @obj_name;
Mise à jour 0
Scénario: J'ai un serveur A qui a deux bases de données (base de données1 et (base de données2). J'ai créé synonyme dans la base de données1. Créer synonyme [DBO]. [Synonyme] pour la base de données2. [DGNOM] Comment écrire une requête communément à Obtenez Object_ID pour ce scénario et objet distant?
Comme l'a mentionné Scott Hodgin, vous pouvez utiliser PARSENAME()
pour vous débarrasser de la partie de votre objet de Remote_Server comme ceci:
declare @cmd varchar(8000) = (select
'select object_id(' +
quotename (
PARSENAME(base_object_name,3) + '.' +
PARSENAME(base_object_name,2) + '.' +
PARSENAME(base_object_name,1), '''')+ ')'
from sys.synonyms )
exec (@cmd) at [server_A];
Mettre à jour 1
Je veux savoir si je peux accéder à la procédure stockée du serveur distant (serveur B) à partir du serveur local (serveur A).
...
Je ne peux pas obtenir la liste de la procédure stockée.
Vous pouvez obtenir la liste des procédures stockées à distance à l'aide de ce code:
select *
from remote_server.remote_db.sys.objects
where type = 'p';
J'ai suscité sépupic réponse.
C'est un autre exemple de la façon dont vous pourriez faire cela - il peut être nécessaire d'être ajusté selon vos besoins.
J'utilise dynamique SQL et sp_columns .
Dans mon exemple, j'ai créé un synonyme appelé syntest
comme suit:
CREATE SYNONYM [dbo].[SynTest] FOR [SqlCompare].[SCOPERATIONAL_DBCC].[SCFBDM].[CFG_LINE_BUS]
Ce synonyme pointe sur le serveur SqlCompare
, base de données SCOPERATIONAL_DBCC
, schéma SCFBDM
et table CFG_LINE_BUS
.
Émettre select * from sys.synonyms where name = 'syntest'
révèle un nom de base_object de [SqlCompare].[SCOPERATIONAL_DBCC].[SCFBDM].[CFG_LINE_BUS]
. Je peux utiliser PARSENAME Pour extraire les parties individuelles de la base_Object_name pour construire l'instruction SQL dynamique
Declare @Cmd nvarchar(4000)
select @Cmd =
'exec ' + PARSENAME(base_object_name,4) + '.' +
PARSENAME(base_object_name,3) +
'.dbo.sp_columns @table_name = ' + '''' +
PARSENAME(base_object_name,1) +
''',@table_owner = ' +
'''' + PARSENAME(base_object_name,2) + ''''
from sys.synonyms where name = 'syntest' --<<<< The name of your synonym
PRINT @CMD
exec sp_executesql @cmd
L'instruction PRINT
montre le SQL dynamique construit comme étant
exec SqlCompare.SCOPERATIONAL_DBCC.dbo.sp_columns @table_name = 'CFG_LINE_BUS',@table_owner = 'SCFBDM'