Komunikaty o błędach podczas wykonywania aktualizacji, wstawiania lub usuwania instrukcji Transact-SQL w tabeli zdalnej za pomocą funkcji OpenQuery: "7357" i "7320"

Symptomy

Zapytania rozproszone korzystające z funkcji OPENQUERY w celu aktualizowania, usuwania lub wstawiania danych w następujący sposób

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

może generować następujące komunikaty o błędach:

Serwer: MSG 7357, Level 16, State 2, wiersz 1 nie można przetworzyć obiektu "Update testlinked Set SSN = SSN". Dostawca OLE DB "SQLOLEDB" wskazuje, że obiekt nie zawiera kolumn. Serwer: MSG 7357, Level 16, State 2, Line 1 [Microsoft] [ODBC SQL Server Driver] [SQL Server] nie można przetworzyć obiektu "Update testlinked Set SSN = SSN". Dostawca OLE DB "MSDASQL" wskazuje, że obiekt nie ma kolumn.

Rzeczywisty komunikat tekstowy błędu może być różny w zależności od dostawcy OLE DB oraz operacji (UPDATE, INSERT lub DELETE), ale numer błędu jest zawsze 7357. Jeśli korzystasz z programu Microsoft SQL Server 2005, zostanie wyświetlony następujący komunikat o błędzie:

Serwer: MSG 7357, poziom 16, stan 2, linia 1 nie może przetworzyć obiektu "Update testlinked Set SSN = SSN". Dostawca OLE DB "SQLOLEDB" dla połączonego serwera "nazwa_serwera" wskazuje, że obiekt nie ma kolumn lub bieżący użytkownik nie ma uprawnień do tego obiektu.

Przyczyna

OPENQUERY wymaga zwrócenia zestawu wyników, ale instrukcje Update, DELETE i Insert używane z opcją OPENQUERY nie zwracają zestawu wyników.

Obejście

Ten problem można obejść na następujące sposoby:

  1. Aby wykonać operacje INSERT, Update lub DELETE, użyj nazw czterech części (linked_server_name. Catalog. Schema. object_name).

  2. Jak opisano w dokumentacji książki online programu SQL Server, należy odwołać się do funkcji OPENQUERY jako tabeli docelowej instrukcji INSERT, Update lub DELETE, pod warunkiem możliwości dostawcy OLE DB. Poniższe zapytania demonstrują właściwe użycie u dostawcy OLE DB programu 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')

    Uwaga W instrukcji INSERT użyto predykatu WHERE 1 = 0, aby uniknąć pobierania danych z serwera zdalnego, co może powodować wolniejszą wydajność. Ponadto operacje aktualizowania i usuwania mają specjalne wymagania dotyczące indeksu; Aby uzyskać szczegółowe informacje, zobacz sekcję "więcej informacji".

Więcej informacji

Wymaganie dotyczące indeksu unikatowego

Dostawca OLE DB programu SQL Server wymaga, aby w tabeli źródłowej istniał indeks unikatowy dla operacji UPDATE lub DELETE. Jeśli w tabeli zdalnej nie istnieje indeks unikatowy, podczas próby aktualizacji lub usunięcia jest wyświetlany następujący błąd:

Serwer: MSG 7320, poziom 16, stan 2, wiersz 1 nie można wykonać zapytania dotyczącego dostawcy OLE DB "SQLOLEDB". Dostawca nie obsługuje wymaganego interfejsu wyszukiwania wierszy. Dostawca wskazuje, że wystąpiły konflikty z innymi właściwościami lub wymaganiami. [Dostawca OLE/DB zwrócił komunikat: Błędy generowane przez Wieloetapową bazę danych OLE. Zaznacz poszczególne wartości statusu OLE DB (jeśli są dostępne). Nie wykonano żadnej pracy.

Dotyczy to zarówno poleceń OPENQUERY , jak i czterech-części o nazwanych operacjach Update i DELETE. Problem został rozwiązany przez dodanie indeksu unikatowego do zdalnej tabeli.

Dynamiczne wykonywanie z OpenQuery

Czasami może być wskazane użycie zapytania dynamicznego w celu osiągnięcia tego samego skutku przy użyciu funkcji OPENQUERY, jak pokazano w poniższym przykładzie:

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

Potrzebna dalsza pomoc?

Rozwijaj swoje umiejętności
Poznaj szkolenia
Uzyskuj nowe funkcje w pierwszej kolejności
Dołącz do niejawnych testerów firmy Microsoft

Czy te informacje były pomocne?

Dziękujemy za opinię!

Dziękujemy za opinię! Wygląda na to, że połączenie Cię z jednym z naszych agentów pomocy technicznej pakietu Office może być pomocne.

×