Compartir a través de


Comparación de las opciones de ejecución remota de consultas

En SQL Server, hay tres maneras de ejecutar una consulta de forma remota:

  • OPENQUERY
  • OPENROWSET
  • EXECUTE AT

En este artículo se describen estos tres métodos.

OPENQUERY

OPENQUERY (Transact-SQL)

Ejecuta la consulta de paso a través especificada en el servidor vinculado especificado. Este servidor es un origen de datos OLE DB. En una consulta, use OPENQUERY en FROM como si fuera un nombre de tabla. También puede hacer referencia a OPENQUERY como tabla de destino de una instrucción INSERT, UPDATE o DELETE. Esto está sujeto a las capacidades del proveedor OLE DB. Aunque la consulta puede devolver varios conjuntos de resultados, OPENQUERY solo devuelve el primero.

OPENQUERY requiere un servidor vinculado previamente agregado y configurado y un texto de solicitud a un servidor remoto. OPENQUERY no requiere una convención de nombre de cuatro partes para tener acceso a los objetos.

OPENROWSET

OPENROWSET (Transact-SQL)

Contiene toda la información de conexión necesaria para tener acceso a datos remotos desde un origen de datos OLE DB. Es un método alternativo para tener acceso a las tablas de un servidor vinculado y, al mismo tiempo, es un método ad hoc para conectarse y tener acceso a datos remotos utilizando OLE DB. Para referencias más frecuentes a orígenes de datos OLE DB, considere la posibilidad de usar servidores vinculados, PolyBase o conexiones directas entre los dos orígenes de datos mediante herramientas como SQL Server Integration Services (SSIS) o aplicaciones personalizadas.

En una consulta, use OPENROWSET en la cláusula FROM de una consulta. También puede usar OPENROWSET como la tabla de destino de una instrucción INSERT, UPDATE o DELETE, según cuál sea la funcionalidad del proveedor OLE DB. Aunque la consulta puede devolver varios conjuntos de resultados, OPENROWSET solo devuelve el primero.

OPENROWSET también admite operaciones masivas a través de un proveedor BULK integrado, que permite que los datos se lean y se devuelvan como un conjunto de filas.

Para obtener información adicional, OPENROWSET use una cadena de conexión escrita explícitamente.

EXECUTE AT

EXECUTE (Transact-SQL)

Permite que la instancia de SQL dinámica se ejecute en un servidor vinculado. Uno de los parámetros de la llamada EXECUTE es AT, que se diseña para omitir las restricciones OPENQUERY y OPENROWSET. EXECUTE (``<query>``) AT [<linked server>] es un SQL dinámico que puede devolver cualquier número de conjuntos de resultados de un servidor remoto.

Instrucciones para SQL dinámico

Evite el uso de comandos de SQL dinámicos en las aplicaciones y restrinja los permisos de los usuarios con acceso a comandos SQL dinámicos. La construcción de consultas para ejecutarlas a través de EXECUTE puede crear vulnerabilidades en sitios web y aplicaciones a través ataques por inyección de código SQL. Para obtener más información, consulte SQL Injection.

Cuando el rendimiento sea un problema, pruebe las consultas remotas:

  • Asegúrese de que se ejecuta tanta lógica como sea posible en el servidor remoto.
  • Compruebe los índices de las tablas de índice de servidor remoto correctamente para admitir la consulta.
  • Tenga en cuenta que el uso de consultas remotas en un código base complica el control de versiones del código de base de datos y el mantenimiento de entornos de desarrollo y pruebas.

Ejemplos

A. Ejecución de una consulta de paso a través SELECT con OPENQUERY

En este ejemplo se usa una consulta SELECT de paso a través para seleccionar las filas con OPENQUERY:

SELECT * 
    FROM OPENQUERY ([linkedserver], 
        'SELECT * FROM AdventureWorksLT.SalesLT.Customer');  

B. Ejecución de una consulta de paso a través SELECT con OPENROWSET

En este ejemplo se usa una consulta SELECT de paso a través para seleccionar las filas con OPENROWSET:

SELECT a.*
FROM OPENROWSET('MSOLEDBSQL', [linkedserver],
     'SELECT * FROM AdventureWorksLT.SalesLT.Customer') AS a;

SQL Server Native Client (a menudo abreviado SNAC) se ha quitado de SQL Server 2022 (16.x) y SQL Server Management Studio 19 (SSMS). Para nuevos trabajos de desarrollo, no se recomiendan ni el proveedor OLE DB de SQL Server Native Client (SQLNCLI o SQLNCLI11) ni el proveedor OLE DB de Microsoft para SQL Server (SQLOLEDB) heredado. Utilice el nuevo Controlador Microsoft OLE DB para SQL Server de ahora en adelante.

C. Ejecución de una consulta de paso a través SELECT con EXECUTE AT

En este ejemplo se usa una consulta SELECT de paso a través para seleccionar las filas con EXECUTE ... AT.

EXECUTE ('SELECT * FROM AdventureWorksLT.SalesLT.Customer') AT [linkedserver]

D. Ejecución de varias instrucciones SELECT

En el ejemplo siguiente se usa una consulta SELECT de paso a través y se obtienen de varios conjuntos de resultados.

EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer;
    SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.CustomerAddress;') AT [linkedserver];

E. Ejecución de una instrucción SELECT y paso de dos argumentos

En el ejemplo siguiente se usa un SELECT de paso a través con dos argumentos.

EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer 
WHERE CustomerID = ? AND LastName = ?', 10, 'Garza') AT [linkedserver];

F. Ejecución de una instrucción SELECT y paso de dos argumentos mediante variables

En el ejemplo siguiente se usa una instrucción SELECT de paso a través con dos argumentos mediante variables.

DECLARE @CustomerID AS INT
DECLARE @LastName AS VARCHAR(100)
SET @CustomerID = 10
SET @LastName = 'Garza'
EXECUTE ('SELECT TOP 10 * FROM AdventureWorksLT.SalesLT.Customer 
WHERE CustomerID = ? AND LastName = ?', @CustomerID, @LastName) AT [linkedserver];

G. Ejecución de instrucciones DDL con EXECUTE mediante servidores vinculados

En el ejemplo siguiente se usa una instrucción DDL en el servidor vinculado.

EXECUTE (
'USE TempDB
IF OBJECT_ID(''dbo.Table1'') IS NOT NULL
DROP TABLE dbo.Table1
CREATE TABLE dbo.Table1
(
    Column1 INT
)' ) AT [linkedserver];

Una vez que haya terminado con las pruebas, limpie los objetos creados.

EXECUTE (
'USE TempDB
IF OBJECT_ID(''dbo.Table1'') IS NOT NULL
DROP TABLE dbo.Table1'
) AT [linkedserver];
EXECUTE sp_dropserver 'linkedserver'

Otros ejemplos

Para obtener más ejemplos del uso de INSERT...SELECT * FROM OPENROWSET(BULK...), vea los siguientes temas:

Consulte también