Parte 3 — Specialized Tables no SQL Server 2025: External Tables

Introdução

Até aqui as tabelas da série guardavam dados dentro do banco. As external tables fazem o contrário: são só metadados que apontam para dados que estão fora dele, seja em outra instância SQL Server, em Oracle, em arquivos Parquet e CSV no Azure Blob Storage, no ADLS Gen2 ou em storage compatível com S3. É a base do que a Microsoft chama de data virtualization via PolyBase: consultar sem copiar, sem ETL.

Como funciona

O PolyBase monta a consulta em quatro peças, sempre nesta ordem:

  1. DATABASE MASTER KEY: protege os segredos guardados no banco.
  2. DATABASE SCOPED CREDENTIAL: usuário e senha, SAS token ou access key do destino.
  3. EXTERNAL DATA SOURCE: onde estão os dados, com prefixo de conector (sqlserver://, oracle://, abs://, adls://, s3://…).
  4. EXTERNAL FILE FORMAT (só para arquivos) e EXTERNAL TABLE: o schema que o T-SQL enxerga.

Com PUSHDOWN = ON, filtros e agregações são executados na origem, trafegando menos dados.

Mão na massa: SQL Server consultando SQL Server

Para ficar 100% reproduzível sem conta na nuvem, vamos usar a própria instância como origem (loopback). Requisito: a feature PolyBase Query Service for External Data instalada no setup e um login SQL (autenticação mista habilitada).

-- 1. Habilita o PolyBase na instância
USE master;
GO
EXEC sp_configure 'polybase enabled', 1;
RECONFIGURE;
GO

-- 2. Banco de origem simulando um sistema externo
CREATE DATABASE DP800_Origem;
GO
USE DP800_Origem;
GO
CREATE TABLE dbo.Cliente
(
    ClienteId INT           NOT NULL PRIMARY KEY,
    Nome      NVARCHAR(100) NOT NULL,
    UF        CHAR(2)       NOT NULL
);
INSERT INTO dbo.Cliente VALUES
    (1, N'Padaria do Zé', 'SP'),
    (2, N'Mercado Sol',   'RJ'),
    (3, N'Tech Sul',      'RS');
GO

-- Login SQL que o PolyBase usará para ler a origem (troque a senha!)
USE master;
GO
CREATE LOGIN polybase_leitor WITH PASSWORD = 'Troque@Esta#Senha2025';
GO
USE DP800_Origem;
GO
CREATE USER polybase_leitor FOR LOGIN polybase_leitor;
ALTER ROLE db_datareader ADD MEMBER polybase_leitor;
GO

-- 3. No banco de laboratório: master key + credential
USE DP800_Lab;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'Master@Key#DP800!';
GO
CREATE DATABASE SCOPED CREDENTIAL cred_Origem
WITH IDENTITY = 'polybase_leitor', SECRET = 'Troque@Esta#Senha2025';
GO

-- 4. External data source (TrustServerCertificate por causa do certificado autoassinado)
CREATE EXTERNAL DATA SOURCE ds_SqlOrigem
WITH
(
    LOCATION           = 'sqlserver://localhost',
    PUSHDOWN           = ON,
    CREDENTIAL         = cred_Origem,
    CONNECTION_OPTIONS = 'TrustServerCertificate=Yes'
);
GO

-- 5. External table: o schema precisa bater com a origem
CREATE EXTERNAL TABLE dbo.ext_Cliente
(
    ClienteId INT           NOT NULL,
    Nome      NVARCHAR(100) NOT NULL,
    UF        CHAR(2)       NOT NULL
)
WITH
(
    LOCATION    = 'DP800_Origem.dbo.Cliente',  -- banco.schema.tabela
    DATA_SOURCE = ds_SqlOrigem
);
GO

-- 6. Consultando como se fosse local (inclusive com JOIN em tabela local)
SELECT * FROM dbo.ext_Cliente WHERE UF = 'RS';

-- Cria estatística para ajudar o otimizador na external table
CREATE STATISTICS st_ext_Cliente_UF ON dbo.ext_Cliente (UF) WITH FULLSCAN;

-- 7. Metadados do que foi criado
SELECT name, location, pushdown FROM sys.external_data_sources;
SELECT name, location            FROM sys.external_tables;

Mão na massa: arquivos Parquet e CSV no storage

Aqui você precisa de uma storage account sua. Troque <conta>, <container> e o SAS token pelos seus valores.

USE DP800_Lab;
GO

-- Credential com SAS token (sem o '?' inicial)
CREATE DATABASE SCOPED CREDENTIAL cred_Blob
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
     SECRET   = '<seu-sas-token>';
GO

CREATE EXTERNAL DATA SOURCE ds_Blob
WITH
(
    LOCATION   = 'abs://<container>@<conta>.blob.core.windows.net',
    CREDENTIAL = cred_Blob
);
GO

-- File format Parquet
CREATE EXTERNAL FILE FORMAT ff_Parquet
WITH (FORMAT_TYPE = PARQUET);
GO

-- Consulta ad hoc, sem criar tabela: OPENROWSET com schema inferido
SELECT TOP (10) *
FROM OPENROWSET
(
    BULK 'vendas/2025/*.parquet',
    DATA_SOURCE = 'ds_Blob',
    FORMAT      = 'PARQUET'
) AS v;

-- External table sobre uma pasta inteira de arquivos Parquet
CREATE EXTERNAL TABLE dbo.ext_Vendas
(
    VendaId   INT,
    ClienteId INT,
    Valor     DECIMAL(10,2),
    DataVenda DATE
)
WITH
(
    LOCATION    = 'vendas/2025/',
    DATA_SOURCE = ds_Blob,
    FILE_FORMAT = ff_Parquet
);
GO

-- CETAS: exporta o resultado de uma query para Parquet no storage
EXEC sp_configure 'allow polybase export', 1;
RECONFIGURE;
GO
CREATE EXTERNAL TABLE dbo.ext_ResumoUF
WITH
(
    LOCATION    = 'resumo/uf/',
    DATA_SOURCE = ds_Blob,
    FILE_FORMAT = ff_Parquet
)
AS
SELECT UF, COUNT(*) AS Qtde
FROM dbo.ext_Cliente
GROUP BY UF;

Pegadinhas

  • External tables são somente leitura para INSERT, UPDATE e DELETE. Para escrever no storage use CETAS.
  • Não há índices em external tables; para ajudar o otimizador, crie estatísticas.
  • Desde o SQL Server 2022, conectividade com Hadoop e scale-out groups do PolyBase foram removidas. Os prefixos atuais são abs://, adls:// e s3:// para arquivos.
  • A ordem de criação importa: sem master key não há credential; sem credential o data source falha na primeira consulta.
  • O schema da external table é validado na criação para fontes ODBC (sqlserver://, oracle://), mas para arquivos o erro só aparece ao consultar.

Conclusão

External tables mudam a pergunta de “como trago esses dados para o banco?” para “preciso mesmo trazer?”. Para a DP-800, a sequência de objetos e a diferença entre external table, OPENROWSET e CETAS valem ouro. No próximo post vamos para o mundo da confiança verificável com as ledger tables.

Link para os scripts no GitHub

-- Limpeza opcional desta parte
USE DP800_Lab;
DROP EXTERNAL TABLE IF EXISTS dbo.ext_Cliente;
DROP EXTERNAL DATA SOURCE ds_SqlOrigem;
DROP DATABASE SCOPED CREDENTIAL cred_Origem;
USE master;
DROP DATABASE IF EXISTS DP800_Origem;
DROP LOGIN polybase_leitor;

Deixe um comentário

Este site utiliza o Akismet para reduzir spam. Saiba como seus dados em comentários são processados.