Referência do Transact-SQL


Manuais Online do SQL Server 2008 (julho de 2009)
WITH common_table_expression (Transact-SQL)

Atualização: 26 de fevereiro de 2009

Especifica um conjunto de resultados nomeado temporário, conhecido como uma expressão de tabela comum (CTE). Ela é derivada de uma consulta simples e definida no escopo de execução de uma única instrução SELECT, INSERT, UPDATE, MERGE ou DELETE. Esta cláusula também pode ser usada em uma instrução CREATE VIEW como parte da instrução SELECT que a define. Uma expressão de tabela comum pode incluir referências a si mesma. É o que chamamos de expressão de tabela comum recursiva.

Ícone de vínculo de tópico Convenções de sintaxe Transact-SQL

Sintaxe

[ WITH <common_table_expression> [ ,...n ] ]

<common_table_expression>::=
        expression_name [ ( column_name [ ,...n ] ) ]
    AS
        ( CTE_query_definition )
Argumentos

expression_name

É um identificador válido para a expressão de tabela comum. expression_name deve ser diferente do nome de qualquer outra expressão de tabela comum definida na mesma cláusula WITH <common_table_expression>, mas expression_name pode ser o mesmo que o nome de uma tabela base ou exibição. Qualquer referência a expression_name na consulta usa a expressão de tabela comum, e não o objeto base.

column_name

Especifica um nome de coluna na expressão de tabela comum. Não são permitidos nomes duplicados em uma única definição de CTE. O número de nomes de coluna especificado deve corresponder ao número de colunas no conjunto de resultados da CTE_query_definition. A lista de nomes de colunas será opcional somente se forem fornecidos nomes distintos para todas as colunas resultantes na definição da consulta.

CTE_query_definition

Especifica uma instrução SELECT cujo conjunto de resultados preenche a expressão de tabela comum. A instrução SELECT da CTE_query_definition deve atender aos mesmos requisitos que os da criação de uma exibição, com a exceção de que uma CTE não pode definir outra CTE. Para obter mais informações, consulte a seção Comentários e CREATE VIEW (Transact-SQL).

Se mais de uma CTE_query_definition for definida, as definições da consulta deverão ser unidas por um destes operadores de conjunto: UNION ALL, UNION, EXCEPT ou INTERSECT. Para obter mais informações sobre como usar definições de consulta CTE recursivas, consulte a seção "Comentários" a seguir e Consultas recursivas que usam expressões de tabelas comuns.

Comentários

Diretrizes para criar e usar expressões de tabela comuns

As diretrizes a seguir se aplicam a expressões de tabela comuns não recursivas. Para verificar as diretrizes relacionadas a expressões de tabela comuns recursivas, consulte "Diretrizes para definir e usar expressões de tabela comuns recursivas" a seguir.

  • Uma CTE deve ser seguida por uma única instrução SELECT, INSERT, UPDATE, MERGE ou DELETE que faça referência a algumas ou a todas as colunas da CTE. Uma CTE também pode ser especificada em uma instrução CREATE VIEW como parte da instrução SELECT que define a exibição.
  • É possível ter várias definições de consulta CTE em uma CTE não recursiva. As definições devem ser combinadas por um destes operadores de conjunto: UNION ALL, UNION, INTERSECT ou EXCEPT.
  • Uma CTE pode fazer referência a si mesma e a CTEs definidas anteriormente na mesma cláusula WITH. Não é permitido referência antecipada.
  • Não é permitida a especificação de mais de uma cláusula WITH em uma CTE. Por exemplo, se uma CTE_query_definition contiver uma subconsulta, essa subconsulta não poderá conter uma cláusula WITH aninhada que defina outra CTE.
  • As seguintes cláusulas não podem ser usadas na CTE_query_definition:
    • COMPUTE ou COMPUTE BY
    • ORDER BY (exceto quando uma cláusula TOP for especificada)
    • INTO
    • Cláusula OPTION com dicas de consulta
    • FOR XML
    • FOR BROWSE
  • Quando uma CTE for usada em uma instrução que faça parte de um lote, a instrução anterior a ela deverá ser seguida por um ponto-e-vírgula.
  • Uma consulta que faça referência a uma CTE pode ser usada para definir um cursor.
  • As tabelas em servidores remotos podem ser referenciadas na CTE.
  • Ao executar uma CTE, quaisquer dicas que façam referência a uma CTE podem ficar em conflito com outras dicas que forem descobertas quando a CTE acessar suas tabelas subjacentes, da mesma maneira que as dicas que façam referência a exibições em consultas. Quando isso acontece, a consulta retorna um erro. Para obter mais informações, consulte Resolução de exibição.
  • Quando uma CTE for o destino de uma instrução UPDATE, todas as referências à CTE na instrução devem ser correspondentes. Por exemplo, se for atribuído à CTE um alias na cláusula FROM, o alias deverá ser usado para todas as outras referências à CTE. Referências ambíguas à CTE podem gerar comportamento de junção inesperado e resultados de consulta não intencionais. Para obter mais informações, consulte UPDATE (Transact-SQL).

Diretrizes para definir e usar expressões de tabela comuns recursivas

As seguintes diretrizes aplicam-se à definição de uma expressão de tabela comum recursiva:

  • A definição da CTE recursiva deve conter pelo menos duas definições de consulta de CTE, um membro de ancoragem e um membro recursivo. É possível definir vários membros de ancoragem e membros recursivos; porém, todas as definições de consulta de membro de ancoragem devem ser colocadas antes da primeira definição de membro recursivo. Todas as definições de consulta CTE são membros de ancoragem, a menos que façam referência à própria CTE.
  • Os membros de ancoragem devem ser combinados por um destes operadores de conjunto: UNION ALL, UNION, INTERSECT ou EXCEPT. UNION ALL é o único operador de conjunto permitido entre o último membro de ancoragem e o primeiro membro recursivo e ao combinar vários membros recursivos.
  • O número de colunas nos membros de ancoragem e recursivos deve ser o mesmo.
  • O tipo de dados de uma coluna no membro recursivo deve ser o mesmo que o tipo de dados da coluna correspondente no membro de ancoragem.
  • A cláusula FROM de um membro recursivo deve fazer referência apenas uma vez à CTE expression_name.
  • Os seguintes itens não são permitidos na CTE_query_definition de um membro recursivo:
    • SELECT DISTINCT
    • GROUP BY
    • HAVING
    • Agregação escalar
    • TOP
    • LEFT, RIGHT, OUTER JOIN (INNER JOIN é permitido)
    • Subconsultas
    • Uma dica aplicada a uma referência recursiva para uma CTE dentro de uma CTE_query_definition.

As seguintes diretrizes aplicam-se ao uso de uma expressão de tabela comum recursiva:

  • Todas as colunas retornadas pela CTE recursiva aceitam valores nulos, independentemente da possibilidade de nulidade das colunas retornadas pelas instruções SELECT participantes.
  • Uma CTE recursiva incorretamente composta pode causar um loop infinito. Por exemplo, se a definição de consulta do membro recursivo retornar os mesmos valores para as colunas pai e filha, um loop infinito será criado. Para evitar um loop infinito, é possível limitar o número de níveis de recursão permitidos para uma instrução específica, usando a dica MAXRECURSION e um valor entre 0 e 32.767 na cláusula OPTION da instrução INSERT, UPDATE, MERGE, DELETE ou SELECT. Isso permite controlar a execução da instrução até que você resolva o problema de código que está criando o loop. O padrão para todo o servidor é 100. Quando 0 for especificado, nenhum limite será aplicado. Apenas um valor MAXRECURSION pode ser especificado por instrução. Para obter mais informações, consulte dicas de consulta (Transact-SQL).
  • Uma exibição que contém uma expressão de tabela comum recursiva não pode ser usada para atualizar dados.
  • É possível definir cursores em consultas usando CTEs. CTE é o argumento select_statement que define o conjunto de resultados do cursor. Apenas cursores de somente avanço rápido e estáticos (instantâneo) são permitidos para CTEs recursivas. Se outro tipo de cursor for especificado em uma CTE recursiva, o tipo de cursor será convertido em estático.
  • As tabelas em servidores remotos podem ser referenciadas na CTE. Se o servidor remoto for referenciado no membro recursivo da CTE, um spool será criado para cada tabela remota, de maneira que as tabelas possam ser acessadas localmente várias vezes. Se essa for uma consulta CTE, Index Spool/Lazy Spools será exibido no plano de consulta e terá o predicado adicional WITH STACK. Essa é uma maneira de confirmar a recursão correta.
  • O SQL Server 2008 não permite funções analíticas e de agregação na parte recursiva da CTE.
Exemplos

A. Criando uma expressão de tabela comum simples

O exemplo a seguir mostra o número de funcionários subordinados diretamente a cada gerente na Ciclos da Adventure Works.

B. Usando uma expressão de tabela comum para limitar contagens e médias de relatório

O exemplo a seguir mostra o número médio de funcionários subordinados a gerentes.

C. Fazendo referência a uma expressão de tabela comum mais de uma vez

O exemplo a seguir mostra o número total de ordens de venda e a data da ordem de venda mais recente na tabela SalesOrderHeader para cada vendedor. Na instrução em execução, a CTE é referenciada duas vezes: uma para retornar as colunas selecionadas para o vendedor e novamente para recuperar detalhes semelhantes para o gerente do vendedor. Os dados para o vendedor e o gerente são retornados em uma única linha.

D. Usando uma expressão de tabela comum recursiva para exibir vários níveis de recursão

O exemplo a seguir mostra a lista hierárquica de gerentes e os funcionários subordinados a eles.

E. Usando uma expressão de tabela comum recursiva para exibir dois níveis de recursão

O exemplo a seguir mostra os gerentes e os funcionários subordinados a eles. O número de níveis retornado está limitado a dois.

F. Usando uma expressão de tabela comum recursiva para exibir uma lista hierárquica

O exemplo a seguir é construído com base no exemplo C com a adição dos nomes do gerente e dos funcionários, e seus respectivos cargos. A hierarquia de gerentes e funcionários é evidenciada pelo recuo de cada nível.

G. Usando MAXRECURSION para cancelar uma instrução

MAXRECURSION pode ser usado para impedir que uma CTE recursiva mal formada entre em um loop infinito. O exemplo a seguir cria um loop infinito intencionalmente e usa a dica MAXRECURSION para limitar o número de níveis de recursão a dois.

USE AdventureWorks;
GO
--Creates an infinite loop
WITH cte (EmployeeID, ManagerID, Title) as
(
    SELECT EmployeeID, ManagerID, Title
    FROM HumanResources.Employee
    WHERE ManagerID IS NOT NULL
  UNION ALL
    SELECT cte.EmployeeID, cte.ManagerID, cte.Title
    FROM cte 
    JOIN  HumanResources.Employee AS e 
        ON cte.ManagerID = e.EmployeeID
)
--Uses MAXRECURSION to limit the recursive levels to 2
SELECT EmployeeID, ManagerID, Title
FROM cte
OPTION (MAXRECURSION 2);
GO

Depois que o erro de codificação for corrigido, MAXRECURSION não será mais necessário. O exemplo a seguir mostra o código corrigido.

H. Usando uma expressão de tabela comum para percorrer seletivamente uma relação recursiva em uma instrução SELECT

O exemplo a seguir mostra a hierarquia de assemblies e componentes do produto necessários para montar a bicicleta para ProductAssemblyID = 800.

I. Usando uma CTE recursiva em uma instrução UPDATE

O exemplo a seguir atualiza o valor de VacationHours em 25 por cento para todos os funcionários subordinados direta ou indiretamente ao ManagerID 12. A expressão de tabela comum retorna uma lista hierárquica de funcionários subordinados diretamente ao ManagerID 12 e funcionários subordinados a esses funcionários, e assim por diante. Somente as linhas retornadas pela expressão de tabela comum são modificadas.

J. Usando vários membros de ancoragem e recursivos

O exemplo a seguir usa vários membros de ancoragem e recursivos para retornar todos os ancestrais de uma pessoa específica. Uma tabela é criada e valores inseridos para estabelecer a genealogia familiar retornada pela CTE recursiva.

Consulte também

Referência

CREATE VIEW (Transact-SQL)
DELETE (Transact-SQL)
EXCEPT e INTERSECT (Transact-SQL)
INSERT (Transact-SQL)
SELECT (Transact-SQL)
UPDATE (Transact-SQL)
MERGE (Transact-SQL)

Outros recursos

Consultas recursivas que usam expressões de tabelas comuns
Usando expressões de tabela comuns

Ajuda e informações

Obtendo assistência do SQL Server 2008
Histórico de alterações

Conteúdo atualizado

Adicionado um item na seção 'Diretrizes para criar e usar expressões de tabela comuns' que descreve os requisitos de nome da CTE quando uma CTE for o destino de uma instrução UPDATE.

Marcas :


Page view tracker