вторник, 12 мая 2009 г.

Что такое OPENQUERY и чем оно может нам помочь

На днях мне задали задачку (перефразируя):

Есть сервера A, B и С. Сервер A связан с сервером B (т.е. A доступен с B). Сервер B связан с сервером C (т.е. сервер B доступен с C). При этом в соответствии с политикой безопасности сервера A и C "не видят друг-друга" (т.е. связи между ними нет). При этом на сервере A есть некоторые данные, которые нужно получить/обработать в ходе выполнения задания на сервере C. Можно ли такое организовать?

Перефразирую: можно ли каким-либо образом из T-SQL кода открыть соединение к связанному серверу и выполнить какой-то SQL код удаленно? Т.е. в нашем случае: сделать на сервере C что-нибудь такое, чтобы некий SQL код на самом деле выполнился на сервере B (откуда есть доступ к серверу A), а результат вернул нам?

Ответ: можно (только осторожно). Ключом в данном случае является та самая функция OPENQUERY, которая вынесена в заголовок.

Эта функция позволяет выполнить некоторый запрос на связанном сервере (linked server) и использовать его результаты как обычную таблицу:

OPENQUERY (linked_server, 'query')

Например:

SELECT *

FROM

  Table1 t1

  LEFT JOIN OPENQUERY([ServerB], 'SELECT * FROM [ServerA].dbname.dbo.SomeTable') q1 ON q1.ID = t1.ID

Вот еще некоторые факты об OPENQUERY:

  • не допускается передача переменных в качестве аргументов
  • допускается использование не только в запросах на выборку данных, но и в запросах на добавление, обновление и удаление
  • не может использоваться для выполнения расширенных хранимых процедур
  • в случае невнимательного отношения к конфигурированию связанных серверов способна проделать здоровенную дыру в безопасности (как в случае с задачкой выше)

 

HTH
AlexS