Comparar opções de execução remota de consulta

No SQL Server, há três maneiras de executar uma consulta remotamente:

  • OPENQUERY
  • OPENROWSET
  • EXECUTE AT

Este artigo descreve esses três métodos.

OPENQUERY

OPENQUERY (Transact-SQL)

Executa a consulta direta especificada no servidor vinculado definido. Esse servidor é uma fonte de dados OLE DB. Em uma consulta, use OPENQUERY como FROM se fosse um nome de tabela. Você também pode referenciar OPENQUERY como a tabela de destino de um INSERT, UPDATE ou DELETE comando. Isso dependerá dos recursos do provedor OLE DB. Embora a consulta possa retornar vários conjuntos de resultados, OPENQUERY retorna apenas o primeiro.

OPENQUERY requer um servidor vinculado pré-adicionado e configurado e um texto de solicitação para um servidor remoto. Não é necessário usar uma convenção de nomenclatura em quatro partes para acessar objetos em OPENQUERY.

OPENROWSET

OPENROWSET (Transact-SQL)

Inclui todas as informações de conexão necessárias para acessar dados remotos de uma fonte de dados OLE DB. Este método é uma alternativa para acessar tabelas em um servidor vinculado e se trata de um método de uso único e ad hoc para conexão e acesso a dados remotos por meio de OLE DB. Para referências mais frequentes a fontes de dados OLE DB, considere usar servidores vinculados, PolyBase ou conexões diretas entre as duas fontes de dados por meio de ferramentas como o SSIS (SQL Server Integration Services) ou aplicativos personalizados.

Em uma consulta, use OPENROWSET na FROM cláusula de uma consulta. Você também pode usar OPENROWSET como a tabela de destino de uma instrução INSERT, UPDATE ou DELETE, sujeito às capacidades do provedor OLE DB. Embora a consulta possa retornar vários conjuntos de resultados, OPENROWSET retorna somente o primeiro deles.

OPENROWSET também dá suporte a operações em massa por meio de um provedor interno BULK que permite que os dados de um arquivo sejam lidos e retornados como um conjunto de linhas.

Para obter informações adicionais, OPENROWSET use uma cadeia de conexão gravada explicitamente.

EXECUTAR EM

EXECUTE (Transact-SQL)

Permite que o SQL dinâmico seja executado em um servidor vinculado. Um dos parâmetros da chamada EXECUTE é AT, que foi projetado para ignorar as restrições OPENQUERY e OPENROWSET. EXECUTE (``<query>``) AT [<linked server>] é o SQL dinâmico que pode retornar qualquer número de conjuntos de resultados de um servidor remoto.

Diretrizes para SQL dinâmico

Evite o uso de comandos SQL dinâmicos em aplicativos e restrinja as permissões em usuários com acesso a comandos SQL dinâmicos. A construção de consultas a serem executadas por meio EXECUTE pode criar vulnerabilidades para sites e aplicativos por meio de ataques de Injeção de SQL. Para obter mais informações, consulte SQL Injection.

Quando o desempenho for uma preocupação, teste consultas remotas:

  • Verifique se o máximo de lógica possível é executado no servidor remoto
  • Verifique os índices nas tabelas de índice do servidor remoto adequadamente para dar suporte à consulta
  • Lembre-se de que o uso de consultas remotas em uma base de código complica o controle de versão do código do banco de dados e a manutenção de ambientes de desenvolvimento e teste

Exemplos

A. Executar uma consulta de passagem SELECT com OPENQUERY

O exemplo a seguir usa uma consulta SELECT de passagem para selecionar as linhas com OPENQUERY:

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

B. Executar uma consulta de passagem SELECT com OPENROWSET

O exemplo a seguir usa uma consulta pass-through SELECT para selecionar as linhas com OPENROWSET

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

O SQL Server Native Client (geralmente abreviado como SNAC) foi removido do SQL Server 2022 (16.x) e do SSMS (SQL Server Management Studio) 19. O provedor OLE DB do SQL Server Native Client (SQLNCLI ou SQLNCLI11) e o Provedor OLE DB herdado da Microsoft para o SQL Server (SQLOLEDB) não são recomendados para um novo desenvolvimento. Alterne para o novo Driver Microsoft OLE DB (MSOLEDBSQL) para SQL Server a partir de agora.

C. Executar uma consulta de passagem SELECT com EXECUTE AT

O exemplo a seguir usa uma consulta passagem de SELECT para selecionar as linhas com EXECUTE ... AT

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

D. Executar várias instruções SELECT

O exemplo a seguir usa uma consulta de passagem SELECT para obter vários conjuntos de resultados

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

E. Executar um SELECT e passar dois argumentos

O exemplo a seguir usa um "pass-through" SELECT com dois argumentos

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

F. Executar um SELECT e passar dois argumentos, usando variáveis

O exemplo a seguir usa um SELECT de passagem com dois argumentos usando variáveis

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. Executar instruções DDL com EXECUTE usando servidores vinculados

O exemplo a seguir usa uma instrução DDL no Linked Server

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

Depois de terminar o teste, limpe os objetos criados

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

Exemplos adicionais

Para obter exemplos adicionais que mostram o uso INSERT...SELECT * FROM OPENROWSET(BULK...), consulte os seguintes tópicos:

Consulte Também