Simptome

Interogări distribuite care utilizează funcția OpenQuery pentru a actualiza, a șterge sau a insera date în felul următor

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')

pot genera următoarele mesaje de eroare:

Server: MSG 7357, nivel 16, stat 2, linia 1 nu a putut prelucra obiectul ' Update testlinked set SSN = SSN '. Furnizorul OLE DB ' SQLOLEDB ' indică faptul că obiectul nu are coloane. Server: MSG 7357, nivel 16, stat 2, line 1 [Microsoft] [ODBC SQL Server driver] [SQL Server] nu a putut prelucra obiectul ' Update testlinked set SSN = SSN '. Furnizorul OLE DB ' MSDASQL ' indică faptul că obiectul nu are coloane.

Mesajul text real al erorii poate varia în funcție de furnizorul OLE DB și de operațiune (se efectuează actualizarea, INSERAREa sau ștergerea), dar numărul de eroare este întotdeauna 7357. Dacă utilizați Microsoft SQL Server 2005, veți primi următorul mesaj de eroare:

Server: MSG 7357, nivel 16, stat 2, linia 1 nu poate prelucra obiectul "Update testlinked set SSN = SSN". Furnizorul OLE DB "SQLOLEDB" pentru serverul legat "Server" indică faptul că obiectul nu are coloane sau utilizatorul curent nu are permisiuni pentru acel obiect.

Cauză

OpenQuery necesită ca un set de rezultate să fie returnat, dar să actualizeze, să șteargă și să insereze declarații utilizate cu OpenQuery nu returnează un set de rezultate.

Soluție de evitare

Puteți soluționa această problemă în următoarele moduri:

  1. Utilizați nume de patru părți (linked_server_name. catalog. schema. object_name) pentru a face operațiuni de inserare, actualizare sau ștergere.

  2. Așa cum este documentat în SQL Server Books Online, faceți referire la funcția OpenQuery ca tabel țintă al unei declarații Inserare, actualizare sau ștergere, sub rezerva capacităților furnizorului OLE DB. Următoarele interogări demonstrează utilizarea corectă cu furnizorul 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')

    Notă În instrucțiunea Inserare, a where 1 = 0 predicat este utilizat pentru a evita regăsirea datelor de la serverul la distanță, care poate avea ca rezultat o performanță mai lentă. De asemenea, operațiunile de actualizare și Ștergere au cerințe speciale pentru index; consultați secțiunea "mai multe informații" pentru detalii.

Mai multe informații

Cerință de index unic

Furnizorul OLE DB SQL Server necesită ca un index unic să existe în tabelul de bază pentru operațiunile de actualizare sau de ștergere. Dacă nu există un index unic într-un tabel la distanță, apare următoarea eroare atunci când se încearcă o actualizare sau o ștergere:

Server: MSG 7320, nivel 16, stat 2, linia 1 nu a putut executa interogarea împotriva OLE DB Provider ' SQLOLEDB '. Furnizorul nu a putut accepta o interfață de căutare de rânduri necesară. Furnizorul indică faptul că s-au produs conflicte cu alte proprietăți sau cerințe. [Furnizor OLE/DB s-a returnat mesaj: erorile generate de operațiunea OLE DB în mai multe etape. Verificați fiecare valoare de stare OLE DB, dacă este disponibilă. Nu s-a efectuat nicio activitate.

Acest lucru se aplică atât la OpenQuery , cât și la operațiunile cu patru părți, numite actualizare și ștergere. Problema este rezolvată adăugând un index unic în tabelul la distanță.

Execuție dinamică cu OpenQuery

Uneori, poate fi de dorit să utilizați o interogare dinamică pentru a obține același efect utilizând OpenQuery, așa cum se arată în exemplul următor:

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

Aveți nevoie de ajutor suplimentar?

Extindeți-vă competențele
Explorați instruirea
Fiți primul care obține noile caracteristici
Alăturați-vă la Microsoft Insider

V-a fost de ajutor această informație?

Cât de mulțumit sunteți de calitatea traducerii?

Ce v-a afectat experiența?

Aveți feedback suplimentar? (Opțional)

Vă mulțumim pentru feedback!

×