Подтвердить что ты не робот

Почему я получаю ошибку "Тип данных Xml не поддерживается в распределенных запросах" при запросе связанного сервера для данных, отличных от xml?

У меня есть два SQL-сервера (под управлением SQL Server 2008) с именем DATA01 и DATA02. DATA02 имеет определение связанного сервера LINK, которое указывает на DATA01, с соответствующим настройкой сопоставления пользователя. В DATA01 имеется база данных MyDatabase, содержащая эти две таблицы:

CREATE TABLE T_A (
    Id int
)

CREATE TABLE T_B (
    Id int,
    Stuff xml
)

Когда я запускаю эту команду из DATA02, я получаю данные как ожидалось:

SELECT Id FROM LINK.MyDatabase.dbo.T_A;

Однако, когда я запускаю эту команду из DATA02, я получаю сообщение об ошибке:

SELECT Id, Stuff FROM LINK.MyDatabase.dbo.T_B;

Ошибка

Тип данных Xml не поддерживается в распределенных запросах. Удаленный объект "DATA02.MyDatabase.dbo.T_B" имеет столбец xml.

И как ни странно, эта команда:

SELECT Id FROM LINK.MyDatabase.dbo.T_B;

также дает ту же ошибку, , хотя я не SELECT столбца xml! Что происходит?

4b9b3361

Ответ 1

Это недостаток в SQL Server. Простое существование столбца xml таблицы не позволяет ему участвовать в распределенных запросах (например, запрашивается через связанное соединение с сервером). Этот упоминается в документации, хотя и не особенно заметно. Вы можете увидеть основной отчет об ошибке подключения здесь и аналогичный отчет здесь. Последний дает два обхода:

  • Создайте представление [a] без столбца (ов) XML на удаленном сервере и запросите это.

    В вашем примере это будет включать добавление представления в MyDatabase это выглядит так:

    CREATE VIEW V_T_B AS SELECT Id FROM T_B;
    

    Затем вы можете запросить это представление по ссылке, чтобы получить Id данные. Обратите внимание, что что-то вроде

    SELECT Id FROM ( SELECT Id FROM T_B ) T_B;
    

    не работает.

  • Использовать сквозной запрос в форме

    SELECT * from OPENQUERY (... )
    

    Этот метод имеет то преимущество, что не требуется никаких изменений в исходная база данных; недостатком является то, что уже невозможно используйте стандартное четырехзначное именование для локальных и связанных данных. запрос будет выглядеть как

    SELECT Id FROM OPENQUERY(DATA02, 'SELECT Id FROM T_B') T_B;
    

    Обратите внимание, что если вы действительно хотите данные xml, этот метод (вдоль с литьем в и из не-XML-типа):

    SELECT Id, CAST(Stuff AS XML) Stuff 
    FROM OPENQUERY(DATA02, 'SELECT Id, CAST(Stuff AS nvarchar(max)) Stuff 
                            FROM T_B') T_B;
    

Обратите внимание, что ошибка была впервые указана в SQL Server 2005 и остается незафиксированной в SQL Server 2014.

Ответ 2

Попробуйте следующее:

  • Создайте представление на стороне источника с помощью xml для nvarchar (max):

CREATE VIEW vXMLTest В ВИДЕ SELECT cast (Stuff as nvarchar (max)) как STUFF FROM T_B

  • Вы можете выбрать его на стороне назначения с помощью нажатия на xml

SELECT Cast (материал как XML) как материал FROM OPENQUERY (DATA02, 'SELECT Stuff FROM vXMLTest')

Это решение работает для меня в 2008R2.