Почему плохо использовать OPENQUERY на локальном сервере?

Я пишу скрипт, который должен работать с кучей серверов и выбирать из них кучу данных, включая локальный сервер. SQL, необходимый для SELECT нужных мне данных, довольно сложен, поэтому я пишу своего рода специальное представление и использую оператор OPENQUERY для получения данных, поэтому в конечном итоге я зацикливаюсь на таком операторе:

exec('INSERT INTO tabl SELECT * FROM OPENQUERY(@Server, @AdHocView)')

Однако я слышал, что использование OPENQUERY на локальном сервере осуждается. Может ли кто-нибудь уточнить, почему?


person Dlongnecker    schedule 03.03.2010    source источник
comment
проверьте связанные серверы   -  person Andrey    schedule 03.03.2010
comment
Это административный скрипт, поэтому я не беспокоюсь о разрешениях. Мой вопрос, в частности, заключается в том, есть ли какие-либо проблемы, когда скрипт перебирает список серверов и сталкивается с собственным именем сервера? Обычно это вызывает ошибку, сервер не настроен для доступа к данным, которую можно исправить с помощью EXEC sp_serveroption 'LocalServer', 'DATA ACCESS', TRUE   -  person Dlongnecker    schedule 04.03.2010


Ответы (3)


  • Хотя запрос может возвращать несколько наборов результатов, OPENQUERY возвращает только первый.
  • OPENQUERY не принимает переменные в качестве аргументов.
  • OPENQUERY нельзя использовать для выполнения расширенных хранимых процедур на связанном сервере. Однако расширенная хранимая процедура может выполняться на связанном сервере с использованием имени, состоящего из четырех частей.
  • Если хранимая процедура sp_addlinkedserver используется в том же скрипте, учетные данные, используемые на удаленном сервере, жестко запрограммированы в скрипте и видны всем, у кого есть копия.

Ссылка:

person OMG Ponies    schedule 03.03.2010
comment
На днях мне довелось использовать OPENQUERY, и я понял, что ваш 4-й пункт неверен; OPENQUERY работает на связанном сервере, поэтому никакие учетные данные не жестко закодированы. Возможно, вы думаете о OPENROWSET. - person Aaronaught; 07.03.2010
comment
@Aaronaught: Если экземпляр связанного сервера существует, зачем вообще использовать OPENQUERY? Если хранимая процедура sp_addlinkedserver используется в том же скрипте, моя точка зрения заслуживает внимания. - person OMG Ponies; 08.03.2010
comment
Что ж, раз уж вы спросили, на самом деле есть причина использовать OPENQUERY: Производительность. OPENQUERY позволяет обрабатывать запрос на удаленном сервере, в то время как при стандартном именовании из 4 частей необходимо копировать все строки на локальный сервер, что довольно плохо для больших наборов данных. Конечно, это нужно сопоставить с другими компромиссами, о которых вы упомянули. - person Aaronaught; 08.03.2010
comment
@OMGPonies Это старо, но сегодня у меня был еще один пример. Другая причина использования OPENQUERY на связанном сервере заключается в том, что связанный сервер может не использовать SQL, совместимый с SQL, на котором написан ваш код, что делает его некомпилируемым, если вызов SQL должен выполняться нормально. - person Brad; 20.06.2013

В дополнение к тому, что сказал @OMG Ponies, это просто не нужно. Нет причин вводить специальные запросы и семантику распределенных транзакций, если в этом нет необходимости. Когда вы используете OPENQUERY, вы берете на себя все негативные аспекты динамического SQL, включая менее предсказуемые планы и неспособность сервера точно отслеживать зависимости.

OPENQUERY также требует, чтобы локальный пользователь имел разрешения на целевой сервер, что, вероятно, не то, что вам нужно, если только это не административный сценарий. Вы не можете ожидать, что каждый пользователь одной базы данных будет иметь одинаковые разрешения для любой другой базы данных.

person Aaronaught    schedule 03.03.2010

Просто продолжение.

OpenQuery удобен, когда вам нужно сравнить или манипулировать некоторыми наборами строк из хранимых процедур.

например, если вам нужно сравнить результаты с двух серверов (тестового сервера и сервера развертывания) при переходе, например, с SQL Server 2005 на SQL server 2008, вы можете выполнить следующий запрос:

select * into test_table from OpenQuery(testServer, 'exec testdb.dbo.test_sp');
select * into rollout_table from OpenQuery(rolloutServer, 'exec testdb.dbo.test_sp');

select * from test_table
except
select * from rollout_table;

select * from rollout_table
except
select * from test_table;

чтобы увидеть какие-либо расхождения.

person Sergey Kuznetsov    schedule 11.06.2013