Messages d’erreur lors de l’exécution d’une instruction Transact-SQL UPDATE, INSERT ou DELETE sur une table distante à l’aide de la fonction OpenQuery : "7357" et "7320"

Symptômes

Requêtes distribuées utilisant la fonction OPENQUERY pour mettre à jour, supprimer ou insérer des données de la façon suivante

exec sp_dropserver 'linked1', 'droplogins'exec sp_addlinkedserver 'linked1', 'SQL Server'exec sp_setnetname  'linked1', '<servername>'exec sp_addlinkedsrvlogin 'linked1', 'false', null, '<login name>', '<password>'SET ANSI_NULLS ONgoSET ANSI_WARNINGS ONgoselect * from openquery (linked1, 'update testlinked set ssn=ssn+1')select * from openquery (linked1, 'insert into  testlinked  (ssn) values (1000)')select * from openquery (linked1, 'delete from  testlinked  where ssn=1')

risquez de générer les messages d’erreur suivants :

Serveur : MSG 7357, niveau 16, état 2, ligne 1 Impossible de traiter l’objet « mise à jour testlinked Set SSN = SSN ». Le fournisseur OLE DB’SQLOLEDB’indique que l’objet ne comporte pas de colonnes. Serveur : MSG 7357, niveau 16, état 2, ligne 1 [Microsoft] [pilote ODBC SQL Server] [SQL Server] n’a pas pu traiter les mises à jour de l’objet testlinked Set SSN = SSN. Le fournisseur OLE DB’MSDASQL’indique que l’objet ne comporte pas de colonnes.

Le message texte réel de l’erreur peut varier en fonction du fournisseur OLE DB et de l’opération (mise à jour, insertion ou suppression) en cours d’exécution, mais le numéro d’erreur est toujours 7357. Si vous utilisez Microsoft SQL Server 2005, le message d’erreur suivant s’affiche :

Serveur : MSG 7357, niveau 16, état 2, ligne 1 ne peut pas traiter l’objet « mise à jour testlinked Set SSN = SSN ». Le fournisseur OLE DB « SQLOLEDB » pour serveur lié « NomServeur » indique que l’objet ne comporte pas de colonnes ou que l’utilisateur actuel ne dispose pas des autorisations sur cet objet.

Cause

OPENQUERY nécessite le retour d’un jeu de résultats, mais les instructions Update, DELETE et insert qui sont utilisées avec OPENQUERY ne renvoient pas de jeu de résultats.

Solution de contournement

Vous pouvez contourner ce problème de la manière suivante :

  1. Utilisez des noms à quatre parties (linked_server_name. Catalog. Schema. object_name) pour insérer, mettre à jour ou supprimer des opérations.

  2. Comme nous l’avons documenté dans la documentation en ligne de SQL Server, faites référence à la fonction OPENQUERY en tant que table cible d’une instruction INSERT, Update ou Delete, soumise aux fonctionnalités du fournisseur OLE DB. Les requêtes suivantes montrent une utilisation correcte du fournisseur OLE DB SQL Server :

    update openquery(linked1, 'select ssn from testlinked where ssn=2')set ssn=ssn + 1insert openquery(linked1, 'select ssn from testlinked where 1=0') values (1000)delete openquery(linked1, 'select ssn from testlinked where ssn>100')

    Remarque Dans l’instruction INSERT, un prédicat WHERE 1 = 0 est utilisé pour éviter de récupérer des données à partir du serveur distant, ce qui peut entraîner une baisse des performances. De plus, les opérations de mise à jour et de suppression ont des exigences spécifiques en matière d’index ; Pour plus d’informations, consultez la section « informations complémentaires ».

Informations supplémentaires

Obligation d’indexation unique

Le fournisseur OLE DB SQL Server nécessite qu’il existe un index unique sur la table sous-jacente pour les opérations de mise à jour ou de suppression. S’il n’existe pas d’index unique sur une table distante, l’erreur suivante se produit lors de la tentative de mise à jour ou de suppression :

Serveur : MSG 7320, niveau 16, état 2, ligne 1 Impossible d’exécuter une requête sur le fournisseur OLE DB « SQLOLEDB ». Le fournisseur ne peut pas prendre en charge une interface de recherche de lignes requise. Le fournisseur indique qu’un conflit s’est produit avec d’autres propriétés ou exigences. [Le fournisseur OLE/DB a renvoyé le message : une opération OLE DB en plusieurs étapes a généré des erreurs. Vérifiez chaque valeur d’État OLE DB, le cas échéant. Aucun travail n’a été réalisé.

Cela concerne les opérations de mise à jour et de suppression, à la fois pour les éléments et les quatre parties. Le problème est résolu en ajoutant un index unique sur la table distante.

Exécution dynamique avec OpenQuery

Il peut arriver que vous souhaitiez utiliser une requête dynamique pour obtenir le même résultat à l’aide de OPENQUERY, comme le montre l’exemple suivant :

begin tranSET QUOTED_IDENTIFIER OFFSET XACT_ABORT ONdeclare @cmd varchar(2500) declare @cmd1 varchar(2500) declare @var varchar(20) set @var = 'White' declare @var1 varchar(20) set @var1 = 'White1' declare @var2 varchar(20) set @var2 = 'Johnson1'select @cmd = "Update openquery(linked1,'select au_lname, au_fname from pubs.dbo.authorswhere au_lname = ''" + @var + "''' )set au_lname = '" + @var1 + "',au_fname = '" + @var2 + "'"exec ( @cmd )commit transelect * from <servername>.pubs.dbo.authors

Besoin d’aide ?

Développez vos compétences
Découvrez des formations
Accédez aux nouvelles fonctionnalités en avant-première
Rejoindre Microsoft Insider

Ces informations vous ont-elles été utiles ?

Dans quelle mesure êtes-vous satisfait(e) de la qualité de la traduction ?

Qu’est-ce qui a affecté votre expérience ?

Avez-vous d’autres commentaires ? (Facultatif)

Nous vous remercions pour vos commentaires.

×