2010-03-03 33 views
6

Estoy escribiendo un script que se supone que se ejecuta en un montón de servidores y selecciono un montón de datos de ellos, incluido el servidor local. El SQL necesario para SELECCIONAR los datos que necesito es bastante complicado, así que estoy escribiendo una especie de vista ad-hoc, y usando una declaración OPENQUERY para obtener los datos, así que en última instancia termino pasando por un enunciado como este:¿Por qué está mal usar OPENQUERY en un servidor local?

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

Sin embargo, he oído que usar OPENQUERY en el servidor local está mal visto. ¿Podría alguien explicar por qué?

+0

Este es un script administrativo, por lo que no me preocupan los permisos. Mi pregunta, específicamente, es si hay alguna duda cuando el script pasa por la lista de servidores y se ejecuta en su propio nombre de servidor. Esto generalmente arroja un error, el servidor no está configurado para el acceso a los datos, que puede rectificarse mediante EXEC sp_serveroption 'LocalServer', 'DATA ACCESS', TRUE – Dlongnecker

+0

check [servidores vinculados] (http://msdn.microsoft.com/en- us/library/ms188279.aspx) – Andrey

Respuesta

6
  • Aunque la consulta puede devolver varios conjuntos de resultados, OPENQUERY solo devuelve la primera.
  • OPENQUERY no acepta variables para sus argumentos.
  • OPENQUERY no se puede utilizar para ejecutar procedimientos almacenados extendidos en un servidor vinculado. Sin embargo, un procedimiento almacenado extendido se puede ejecutar en un servidor vinculado utilizando un nombre de cuatro partes.
  • Si se utiliza el sp_addlinkedserver procedimiento almacenado dentro de la misma secuencia de comandos, las credenciales utilizadas en el servidor remoto están codificados en el guión, visible para cualquiera que tenga una copia

Referencia:

+0

Tuve ocasión de usar 'OPENQUERY' el otro día y me di cuenta de que su 4to punto era incorrecto; 'OPENQUERY' opera en un servidor vinculado por lo que las credenciales no están codificadas. Usted puede estar pensando en 'OPENROWSET'. – Aaronaught

+0

@Aaronaught: si existe una instancia de servidor vinculado, ¿por qué usar OPENQUERY en absoluto? Si el procedimiento almacenado 'sp_addlinkedserver' se utiliza dentro del mismo script, mi punto tiene sus méritos. –

+1

Bueno, ya que lo preguntaste, en realidad hay una razón para usar 'OPENQUERY': Rendimiento. 'OPENQUERY' permite que la consulta se procese en el servidor remoto, mientras que el nombre estándar de 4 partes tiene que copiar todas las filas al servidor local, lo cual es bastante malo para grandes conjuntos de datos. Por supuesto, esto tiene que sopesarse con las otras compensaciones que ha mencionado. – Aaronaught

2

Además de lo que dijo @OMG Ponies, es simplemente innecesario. No hay ninguna razón para introducir consultas ad-hoc y semánticas de transacciones distribuidas cuando no es necesario. Cuando utiliza OPENQUERY, asume todos los aspectos negativos del SQL dinámico, incluidos los planes menos predecibles y la incapacidad del servidor para rastrear con precisión las dependencias.

OPENQUERY también requiere que el usuario local tenga permisos para el servidor de destino, que probablemente no sea lo que usted desea a menos que sea un script administrativo. No puede esperar que todos los usuarios de una base de datos tengan los mismos permisos para todas las demás bases de datos.

2

Solo una continuación.

OpenQuery es bueno cuando tiene que comparar o manipular algunos conjuntos de filas de procedimientos almacenados.

por ejemplo, si usted tiene que comparar los resultados de dos servidores (de prueba y de distribución del servidor antivirus) cuando migra desde SQL Server 2005 a servidor SQL 2008 por ejemplo, entonces usted puede hacer la siguiente consulta:

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; 

para ver las discrepancias.

Cuestiones relacionadas