Requête d'exemple de serveur lié SQL Server


93

Dans Management Studio, j'essaie d'exécuter une requête / de faire une jointure entre deux serveurs liés. Est-ce une syntaxe correcte utilisant des serveurs de base de données liés:

select foo.id 
from databaseserver1.db1.table1 foo, 
     databaseserver2.db1.table1 bar 
where foo.name=bar.name

Fondamentalement, préférez-vous simplement le nom du serveur db à db.table?

Réponses:


186

Le format devrait probablement être:

<server>.<database>.<schema>.<table>

Par exemple: DatabaseServer1.db1.dbo.table1


Mettre à jour : je sais que c'est une vieille question et la réponse que j'ai est correcte; cependant, je pense que quiconque tombera dessus devrait savoir quelques choses.

A savoir, lors de l'interrogation sur un serveur lié dans une situation de jointure, la table ENTIER du serveur lié sera probablement téléchargée sur le serveur à partir duquel la requête s'exécute afin de réaliser l'opération de jointure. Dans le cas de l'OP, à la fois table1de DB1et table1de DB2seront transférés dans leur intégralité au serveur exécutant la requête, vraisemblablement nommé DB3.

Si vous avez des tables volumineuses, cela peut entraîner une opération qui prend beaucoup de temps à exécuter. Après tout, il est maintenant limité par les vitesses de trafic réseau qui sont des ordres de grandeur plus lentes que la mémoire ou même les vitesses de transfert de disque.

Si possible, effectuez une seule requête sur le serveur distant, sans joindre à une table locale, pour extraire les données dont vous avez besoin dans une table temporaire. Puis interrogez-vous sur cela.

Si ce n'est pas possible, vous devez examiner les différentes choses qui obligeraient le serveur SQL à charger la table entière localement. Par exemple en utilisant GETDATE()ou même certaines jointures. D'autres tueurs de performance incluent ne pas donner les droits appropriés.

Voir http://thomaslarock.com/2013/05/top-3-performance-killers-for-linked-server-queries/ pour plus d'informations.


11
si le nom du
serveur de

4
@ bmw0128: Mieux encore, utilisez des guillemets doubles: il est pris en charge par presque toutes les plates-formes, contrairement aux crochets de Microsoft.

2
Vous devez également utiliser les crochets ou les guillemets doubles lorsque le nom du serveur de base de données comporte un point.
David Brunow

4
Si vous n'êtes pas certain de l'un des qualificatifs, accédez à une table dans un serveur lié dans l'explorateur d'objets SSMS, cliquez avec le bouton droit de la souris et Script Table as, SELECT To et New Query Editor Window. L'instruction SELECT résultante inclura le chemin d'accès complet et correct vers la table. J'avais un qualificatif de base de données mystère en travaillant avec Sybase et cela m'a donné le nom correct.
John Mo du

Je pense que vous avez tort de dire que la table entière sera transférée. Pouvez-vous nous indiquer où vous avez obtenu ces informations? J'ai juste essayé de me joindre à une table avec 204 millions de lignes (16 Go de données, 6,6 Go d'index) sur un serveur lié et il a fallu 47 ms pour se lier à 5 des lignes, 7 ms sur la deuxième requête, car les données étaient probablement mises en cache. Peut-être que si votre jointure nécessitait une analyse de table sur la table liée, elle devrait tout transférer?
Jason Goemaat

32
SELECT * FROM OPENQUERY([SERVER_NAME], 'SELECT * FROM DATABASE_NAME..TABLENAME')

Cela peut vous aider.


J'ai voté pour. Cela fonctionne lorsque vous liez MySQL à MS SQL.
Baz Guvenkaya

3
En d'autres termes, cela crée une requête directe. Gardez à l'esprit que l'instruction de requête doit être écrite dans le SQL natif du serveur. La syntaxe d'Oracle est différente de Teradata différente de SQL Server etc.
AxGryndr

10

Si vous rencontrez toujours un problème avec <server>.<database>.<schema>.<table>

Insérez le nom du serveur dans []


Attention: j'ai exécuté une table de création à partir de select en utilisant [], et au lieu d'être créée sur le serveur lié, la table a été créée localement avec un nom commedbo.databaseserver1.db1.dbo.table1
biscuit314

9

Pour ceux qui ont des problèmes avec ces autres réponses , essayezOPENQUERY

Exemple:

 SELECT * FROM OPENQUERY([LinkedServer], 'select * from [DBName].[schema].[tablename]') 

Works for SQL Server
Tom Stickel

8

Vous devez spécifier le schéma / propriétaire (dbo par défaut) dans le cadre de la référence. En outre, il serait préférable d'utiliser le style de jointure le plus récent (ANSI-92).

select foo.id 
    from databaseserver1.db1.dbo.table1 foo
        inner join databaseserver2.db1.dbo.table1 bar 
            on foo.name = bar.name

la syntaxe de jointure interne est préférable aux jointures implicites?
bmw0128

2
@ bmw0128: Oui, pour plusieurs raisons. À mon humble avis, le plus important est qu'il est trop facile d'écrire accidentellement une jointure entre produits lorsque vous avez vos tables et jointures à deux endroits différents.

Notez que les 4 parties en pointillé NE FONCTIONNENT PAS pour certains serveurs liés non SQL-Server. Cela peut générer une erreur comme ... Un schéma ou un catalogue non valide a été spécifié pour le fournisseur "MSDASQL" pour le serveur lié "MyLinkedServer".
brewmanz

6
select * from [Server].[database].[schema].[tablename] 

C'est la bonne façon d'appeler. Assurez-vous de vérifier que les serveurs sont liés avant d'exécuter la requête!

Pour vérifier les serveurs liés, appelez:

EXEC sys.sp_linkedservers 

Cela NE FONCTIONNE PAS pour certains serveurs liés non-SQL-Server. Cela génère une erreur comme ... Un schéma ou un catalogue non valide a été spécifié pour le fournisseur "MSDASQL" pour le serveur lié "MyLinkedServer".
brewmanz

4
select name from drsql01.test.dbo.employee
  • drslq01 est servernmae - sereur lié
  • test est le nom de la base de données
  • dbo est un schéma par défaut
  • employé est le nom de la table

J'espère que cela aide à comprendre, comment exécuter une requête pour le serveur lié


2

Habituellement, les requêtes directes ne doivent pas être utilisées dans le cas d'un serveur lié car il utilise fortement la base de données temporaire du serveur SQL. À la première étape, les données sont extraites dans la base de données temporaire, puis le filtrage se produit. Il existe de nombreux fils à ce sujet. Il est préférable d'utiliser Open OPENQUERY car il transmet SQL au serveur lié source, puis renvoie des résultats filtrés, par exemple

SELECT *
FROM OPENQUERY(Linked_Server_Name , 'select * from TableName where ID = 500')

Cette réponse n'inclut pas de nom de base de données
Chris Nevill

2
J'ai fourni des informations de base de données lors de la création du serveur lié. Pour plus de détails, vous pouvez voir le lien MSDN ci-dessous: msdn.microsoft.com/en-us/library/ff772782(v=sql.110).aspx
Muhammad Yaseen

Que puis-je faire si mon serveur lié nécessite une authentification et que j'essaie simplement de faire une requête à partir de mon application PHP à l'aide de PDO?
nekiala

Comment effectueriez-vous une jointure de la base de données 1 à la base de données sur le serveur lié, en utilisant cette approche?
eaglei22

2

Pour ce que ça vaut, j'ai trouvé la syntaxe suivante qui fonctionnait le mieux:

SELECT * FROM [LINKED_SERVER] ... [TABLE]

Je n'ai pas pu faire fonctionner les recommandations des autres, en utilisant le nom de la base de données. En outre, cette source de données n'a pas de schéma.


2

faites un clic droit sur une table et cliquez sur la table de script comme sélectionnez

entrez la description de l'image ici


Ce n'est pas ce que l'OP a demandé
Fandango68

2
cela montre comment obtenir la syntaxe correcte pour la requête de sélection sur une table liée. le résultat est comme la réponse de seans
Shimon Doodkin

1
@ShimonDoodkin, un excellent exemple de ne me donne pas un poisson, mais apprends-moi à pêcher
Amro

0

Il est préférable de suivre la requête.

Essayez cette requête:

SELECT * FROM OPENQUERY([LINKED_SERVER_NAME], 'SELECT * FROM [DATABASE_NAME].[SCHEMA].[TABLE_NAME]')

Il est très utile de lier MySQL à MS SQL


0

PostgreSQL :

  1. Vous devez fournir un nom de base de données dans le DSN de la source de données .
  2. Exécutez Management Studio en tant qu'administrateur
  3. Vous devez omettre le DBName de la requête :

    SELECT * FROM OPENQUERY([LinkedServer], 'select * from schema."tablename"')

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.