Compartilhar via


sp_describe_first_result_set (Transact-SQL)

Aplica-se a: SQL Server Banco de Dados SQL do Azure Instância Gerenciada de SQL do Azure Azure Synapse Analytics PDW (Analytics Platform System) Ponto de extremidade de análise de SQL no Microsoft Fabric Warehouse no Microsoft Fabric

Retorna os metadados para o primeiro conjunto possível de resultados do lote Transact-SQL. Retorna um conjunto de resultados vazio quando o lote não retorna resultados. Gera um erro se o Mecanismo de Banco de Dados não puder determinar os metadados da primeira consulta que será executada executando uma análise estática. A exibição de gerenciamento dinâmico sys.dm_exec_describe_first_result_set retorna as mesmas informações.

Convenções de sintaxe de Transact-SQL

Sintaxe

sp_describe_first_result_set [ @tsql = ] N'tsql'
    [ , [ @params = ] N'params [ , ...n ]' ]
    [ , [ @browse_information_mode = ] <tinyint> ]
[ ; ]

Argumentos

@tsql [ = ] 'tsql'

Uma ou mais instruções Transact-SQL. @tsql pode ser nvarchar(n) ou nvarchar(max).

@params [ = ] N'params'

@params fornece uma cadeia de caracteres de declaração para parâmetros para o lote Transact-SQL, que é semelhante ao sp_executesql. Os parâmetros podem ser nvarchar(n) ou nvarchar(max).

Uma cadeia de caracteres que contém as definições de todos os parâmetros inseridos no @tsql. A cadeia de caracteres deve ser uma constante Unicode ou uma variável Unicode. Cada definição de parâmetro consiste em um nome de parâmetro e um tipo de dados. n é um espaço reservado que indica definições de parâmetro adicionais. Cada parâmetro especificado na instrução deve ser definido em @params. Se a instrução Transact-SQL ou o lote na instrução não contiver parâmetros, @params não será necessário. NULL é o valor padrão para esse parâmetro.

@browse_information_mode [ = ] tinyint

Especifica se colunas de chave extras e informações da tabela de origem são retornadas. Se definido como 1, cada consulta será analisada como se incluísse uma FOR BROWSE opção na consulta.

  • Se definido como 0, nenhuma informação será retornada.

  • Se definido como 1, cada consulta será analisada como se incluísse uma FOR BROWSE opção na consulta. Isso retorna nomes de tabela base como as informações da coluna de origem.

  • Se definido como 2, cada consulta será analisada como se fosse usada na preparação ou execução de um cursor. Isso retorna nomes de exibição como informações de coluna de origem.

Valores do código de retorno

sp_describe_first_result_set sempre retorna um status zero em caso de êxito. Se o procedimento gerar um erro e o procedimento for chamado como RPC, o status de retorno será preenchido pelo tipo de erro descrito na coluna error_type de sys.dm_exec_describe_first_result_set. Se o procedimento for chamado do Transact-SQL, o valor retornado será sempre zero, mesmo quando houver um erro.

Conjunto de resultados

Estes metadados comuns são retornados como um conjunto de resultados com uma linha para cada coluna nos metadados de resultados. Cada linha descreve o tipo e a nulidade da coluna no formato descrito na seção a seguir. Se a primeira instrução não existir para cada caminho de controle, um conjunto de resultados com zero linhas será retornado.

Nome da coluna Tipo de dados Descrição
is_hidden bit Indica que a coluna é uma coluna extra adicionada para fins de informações de navegação e que ela não aparece no conjunto de resultados. Não permite valor nulo.
column_ordinal int Contém a posição ordinal da coluna no conjunto de resultados. A posição da primeira coluna é especificada como 1. Não permite valor nulo.
name sysname Conterá o nome da coluna se um nome puder ser determinado. Caso contrário, conterá NULL. Anulável.
is_nullable bit Contém o valor 1 se a coluna permitir NULL, 0 se a coluna não permitir NULLe 1 se não puder ser determinado se a coluna permitir NULL. Não permite valor nulo.
system_type_id int Contém o system_type_id tipo de dados da coluna, conforme especificado em sys.types. Para tipos CLR, mesmo que a system_type_name coluna retorne NULL, essa coluna retorna o valor 240. Não permite valor nulo.
system_type_name nvarchar(256) Contém o nome e argumentos (como comprimento, precisão, escala), especificados para o tipo de dados da coluna. Se o tipo de dados for um tipo de alias definido pelo usuário, o tipo de sistema subjacente será especificado aqui. Se for um tipo CLR definido pelo usuário, NULL será retornado nesta coluna. Anulável.
max_length smallint Comprimento máximo (em bytes) da coluna.

-1 = O tipo de dados da coluna é varchar(max), nvarchar(max), varbinary(max) ou xml.

Para colunas de texto , o max_length valor é 16 ou o valor definido por sp_tableoption 'text in row'. Não permite valor nulo.
precision tinyint Precisão da coluna, se tiver base numérica. Caso contrário, retornará 0. Não permite valor nulo.
scale tinyint Escala da coluna, se tiver base numérica. Caso contrário, retornará 0. Não permite valor nulo.
collation_name sysname Nome da ordenação da coluna, se baseada em caracteres. Caso contrário, retornará NULL. Anulável.
user_type_id int Para tipos CLR e alias, contém o user_type_id tipo de dados da coluna, conforme especificado em sys.types. Caso contrário, é NULL. Anulável.
user_type_database sysname Para tipos de CLR e de alias, contém o nome do banco de dados no qual o tipo é definido. Caso contrário, é NULL. Anulável.
user_type_schema sysname Para tipos de CLR e de alias, contém o nome do esquema no qual o tipo é definido. Caso contrário, é NULL. Anulável.
user_type_name sysname Para tipos de CLR e de alias, contém o nome do tipo. Caso contrário, é NULL. Anulável.
assembly_qualified_type_name nvarchar(4000) Para tipos de CLR, retorna o nome do assembly e da classe que define o tipo. Caso contrário, é NULL. Anulável.
xml_collection_id int Contém o xml_collection_id tipo de dados da coluna, conforme especificado em sys.columns. Essa coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquemas XML. Anulável.
xml_collection_database sysname Contém o banco de dados no qual a coleção de esquemas XML associada a esse tipo está definida. Essa coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquemas XML. Anulável.
xml_collection_schema sysname Contém o esquema no qual a coleção de esquemas XML associada a esse tipo está definida. Essa coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquemas XML. Anulável.
xml_collection_name sysname Contém o nome da coleção de esquemas XML associada a esse tipo. Essa coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquemas XML. Anulável.
is_xml_document bit Retorna 1 se o tipo de dados retornado for XML e esse tipo tiver a garantia de ser um documento XML completo (incluindo um nó raiz), em vez de um fragmento XML. Caso contrário, retornará 0. Não permite valor nulo.
is_case_sensitive bit Retorna 1 se a coluna for um tipo de cadeia de caracteres que diferencia maiúsculas de minúsculas e 0 se não for. Não permite valor nulo.
is_fixed_length_clr_type bit Retorna 1 se a coluna for um tipo CLR de comprimento fixo e 0 se não for. Não permite valor nulo.
source_server sysname Nome do servidor de origem retornado pela coluna neste resultado (se a origem for um servidor remoto). O nome é dado como aparece em sys.servers. Retorna NULL se a coluna for originada no servidor local ou se não for possível determinar em qual servidor ela se origina. Será populado somente se informações de navegação forem solicitadas. Anulável.
source_database sysname Nome do banco de dados de origem retornado pela coluna neste resultado. Retorna NULL se o banco de dados não puder ser determinado. Será populado somente se informações de navegação forem solicitadas. Anulável.
source_schema sysname Nome do esquema de origem retornado pela coluna neste resultado. Retorna NULL se o esquema não puder ser determinado. Será populado somente se informações de navegação forem solicitadas. Anulável.
source_table sysname Nome da tabela de origem retornado pela coluna neste resultado. Retorna NULL se a tabela não puder ser determinada. Será populado somente se informações de navegação forem solicitadas. Anulável.
source_column sysname Nome da coluna de origem retornado pela coluna de resultado. Retorna NULL se a coluna não puder ser determinada. Será populado somente se informações de navegação forem solicitadas. Anulável.
is_identity_column bit Retorna 1 se a coluna for uma coluna de identidade e 0 se não. Retorna NULL se não for possível determinar que a coluna é uma coluna de identidade. Anulável.
is_part_of_unique_key bit Retorna 1 se a coluna fizer parte de um índice exclusivo (incluindo restrição exclusiva e primária) e 0 se não. Retorna NULL se não for possível determinar que a coluna faz parte de um índice exclusivo. Será populado somente se informações de navegação forem solicitadas. Anulável.
is_updateable bit Retorna 1 se a coluna for atualizável e 0 se não. Retorna NULL se não for possível determinar que a coluna é atualizável. Anulável.
is_computed_column bit Retorna 1 se a coluna for uma coluna computada e 0 se não. Retorna NULL se não for possível determinar que a coluna é uma coluna computada. Anulável.
is_sparse_column_set bit Retorna 1 se a coluna for uma coluna esparsa e 0 se não. Retorna NULL se não for possível determinar que a coluna faz parte de um conjunto de colunas esparsas. Anulável.
ordinal_in_order_by_list smallint Posição desta coluna na ORDER BY lista. Retorna NULL se a coluna não aparecer na ORDER BY lista ou se a ORDER BY lista não puder ser determinada exclusivamente. Anulável.
order_by_list_length smallint Tamanho da ORDER BY lista. Retorna NULL se não houver nenhuma ORDER BY lista ou se a ORDER BY lista não puder ser determinada exclusivamente. Esse valor é o mesmo para todas as linhas retornadas por sp_describe_first_result_set. Anulável.
order_by_is_descending smallint Se não ordinal_in_order_by_list for NULL, a coluna informará order_by_is_descending a ORDER BY direção da cláusula para essa coluna. Caso contrário, ele relata NULL. Anulável.
tds_type_id int Para uso interno. Não permite valor nulo.
tds_length int Para uso interno. Não permite valor nulo.
tds_collation_id int Para uso interno. Anulável.
tds_collation_sort_id tinyint Para uso interno. Anulável.

Comentários

sp_describe_first_result_set garante que, se o procedimento retornar os primeiros metadados do conjunto de resultados para o lote A (hipotético) e se esse lote (A) for executado, o lote:

  • gera um erro de tempo de otimização
  • gera um erro em tempo de execução
  • Não retorna nenhum conjunto de resultados
  • retorna um primeiro conjunto de resultados com os mesmos metadados descritos por sp_describe_first_result_set

O nome, a nulidade e o tipo de dados podem diferir. Se sp_describe_first_result_set retornar um conjunto de resultados vazio, a garantia é que a execução em lote retornará conjuntos sem resultados.

Essa garantia presume que não há alterações de esquema relevantes no servidor. As alterações de esquema relevantes no servidor não incluem a criação de tabelas temporárias ou variáveis de tabela no lote A entre a hora em que sp_describe_first_result_set é chamada e a hora em que o conjunto de resultados é retornado durante a execução, incluindo alterações de esquema feitas pelo lote B.

sp_describe_first_result_set Retorna um erro em qualquer um dos seguintes casos:

  • O @tsql de entrada não é um lote Transact-SQL válido. A validade é determinada pela análise do lote do Transact-SQL. Quaisquer erros causados pelo lote durante a otimização da consulta ou durante a execução não são considerados ao determinar se o lote Transact-SQL é válido.

  • @params não NULL é e contém uma cadeia de caracteres que não é uma cadeia de caracteres de declaração sintaticamente válida para parâmetros ou se contém uma cadeia de caracteres que declara qualquer parâmetro mais de uma vez.

  • O lote Transact-SQL de entrada declara uma variável local com o mesmo nome que um parâmetro declarado em @params.

  • A instrução usa uma tabela temporária.

  • A consulta inclui a criação de uma tabela permanente que é então consultada.

Se todas as outras verificações forem bem-sucedidas, serão considerados todos os caminhos de fluxo de controle possíveis dentro do lote de entrada. Isso leva em conta todas as instruções de fluxo de controle (GOTO, IF/ELSE, WHILEe blocos Transact-SQL/TRYCATCH), bem como quaisquer procedimentos, lotes dinâmicos do Transact-SQL ou gatilhos invocados do lote de entrada por uma EXEC instrução, uma instrução DDL que faz com que os gatilhos DDL sejam disparados ou uma instrução DML que faz com que os gatilhos sejam disparados em uma tabela de destino ou em uma tabela modificada devido à ação em cascata em uma restrição de chave estrangeira. Em algum momento, como acontece com muitos caminhos de controle possíveis, um algoritmo para.

Para cada caminho de fluxo de controle, a primeira instrução (se houver) que retorna um conjunto de resultados é determinada por sp_describe_first_result_set.

Quando houver várias e possíveis primeiras instruções em um lote, seus resultados podem diferir no número de colunas, no nome da coluna, na nulidade e no tipo de dados. Veja aqui mais detalhadamente como essas diferenças são tratadas:

  • Se o número de colunas diferir, um erro será gerado e nenhum resultado será retornado.

  • Se o nome da coluna for diferente, o nome da coluna retornado será definido como NULL.

  • Se a nulidade for diferente, a nulidade retornada permitirá NULL.

  • Se o tipo de dados for diferente, um erro será lançado e nenhum resultado será retornado, exceto nos seguintes casos:

    • varchar(a) to varchar(a') where a' > a.
    • varchar(a) to varchar(max)
    • nvarchar(a) to nvarchar(a') where a' > a.
    • nvarchar(a) to nvarchar(max)
    • varbinary(a) to varbinary(a') where a' > a.
    • varbinary(a) to varbinary(max)

sp_describe_first_result_set não dá suporte à recursão indireta.

Permissões

Requer permissão para executar o argumento @tsql .

Exemplos

Exemplos típicos

R. Exemplo básico

O exemplo a seguir descreve o conjunto de resultados retornado de uma única consulta.

EXEC sp_describe_first_result_set @tsql = N'SELECT object_id, name, type_desc FROM sys.indexes';

O exemplo a seguir mostra o conjunto de resultados retornado de uma única consulta que contém um parâmetro.

EXEC sp_describe_first_result_set @tsql = N'
SELECT object_id, name, type_desc
FROM sys.indexes
WHERE object_id = @id1',
@params = N'@id1 int';

B. Exemplos do modo de navegação

Os três exemplos a seguir ilustram a principal diferença entre os modos de procurar informações. Somente as colunas relevantes são incluídas nos resultados da consulta.

Exemplo usando 0, indicando que nenhuma informação é retornada.

CREATE TABLE dbo.t (
    a INT PRIMARY KEY,
    b1 INT
);
GO

CREATE VIEW dbo.v AS
SELECT b1 AS b2
FROM dbo.t;
GO

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM dbo.v', NULL, 0;

Este é um conjunto de resultados parcial.

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 b3 NULL NULL NULL NULL

Exemplo que usa 1 indicando que retorna informações como se incluísse uma opção FOR BROWSE na consulta.

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 1;

Este é um conjunto de resultados parcial.

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 b3 dbo t B1 0
1 2 um dbo t um 1

Exemplo usando 2 indicando analisado como se você estivesse preparando um cursor.

EXEC sp_describe_first_result_set N'SELECT b2 AS b3 FROM v', NULL, 2;

Este é o conjunto de resultados.

is_hidden column_ordinal name source_schema source_table source_column is_part_of_unique_key
0 1 B3 dbo v B2 0
1 2 ROWSTAT NULL NULL NULL 0

C. Armazenar resultados em uma tabela

Em alguns cenários, você precisa colocar os resultados do sp_describe_first_result_set procedimento em uma tabela para que possa processar ainda mais o esquema.

Primeiro, você precisa criar uma tabela que corresponda à saída do procedimento sp_describe_first_result_set:

CREATE TABLE #frs (
    is_hidden BIT NOT NULL,
    column_ordinal INT NOT NULL,
    name SYSNAME NULL,
    is_nullable BIT NOT NULL,
    system_type_id INT NOT NULL,
    system_type_name NVARCHAR(256) NULL,
    max_length SMALLINT NOT NULL,
    precision TINYINT NOT NULL,
    scale TINYINT NOT NULL,
    collation_name SYSNAME NULL,
    user_type_id INT NULL,
    user_type_database SYSNAME NULL,
    user_type_schema SYSNAME NULL,
    user_type_name SYSNAME NULL,
    assembly_qualified_type_name NVARCHAR(4000),
    xml_collection_id INT NULL,
    xml_collection_database SYSNAME NULL,
    xml_collection_schema SYSNAME NULL,
    xml_collection_name SYSNAME NULL,
    is_xml_document BIT NOT NULL,
    is_case_sensitive BIT NOT NULL,
    is_fixed_length_clr_type BIT NOT NULL,
    source_server SYSNAME NULL,
    source_database SYSNAME NULL,
    source_schema SYSNAME NULL,
    source_table SYSNAME NULL,
    source_column SYSNAME NULL,
    is_identity_column BIT NULL,
    is_part_of_unique_key BIT NULL,
    is_updateable BIT NULL,
    is_computed_column BIT NULL,
    is_sparse_column_set BIT NULL,
    ordinal_in_order_by_list SMALLINT NULL,
    order_by_list_length SMALLINT NULL,
    order_by_is_descending SMALLINT NULL,
    tds_type_id INT NOT NULL,
    tds_length INT NOT NULL,
    tds_collation_id INT NULL,
    tds_collation_sort_id TINYINT NULL
);

Ao criar uma tabela, você poderá armazenar o esquema de alguma consulta nessa tabela.

DECLARE @tsql NVARCHAR(MAX) = 'select top 0 * from sys.credentials';

INSERT INTO #frs
EXEC sys.sp_describe_first_result_set @tsql;

SELECT * FROM #frs;

Exemplos de problemas

Os exemplos a seguir usam duas tabelas para todos os exemplos. Execute as seguintes instruções para criar as tabelas de exemplo.

CREATE TABLE dbo.t1 (
    a INT NULL,
    b VARCHAR(10) NULL,
    c NVARCHAR(10) NULL
);

CREATE TABLE dbo.t2 (
    a SMALLINT NOT NULL,
    d VARCHAR(20) NOT NULL,
    e INT NOT NULL
);

Erro porque o número de colunas difere

O número de colunas nos possíveis primeiros conjuntos de resultados difere neste exemplo.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT a FROM t1;
ELSE
    SELECT a, b FROM t1;

SELECT * FROM t; -- Ignored, not a possible first result set.';

Erro porque os tipos de dados diferem

Os tipos de colunas diferem nos primeiros possíveis conjuntos de resultados diferentes.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT a FROM t1;
ELSE
    SELECT a FROM t2;';

Isso resulta em um erro de tipos incompatíveis (int vs. smallint).

O nome da coluna não pode ser determinado

As colunas nos primeiros possíveis conjuntos de resultados diferem no comprimento para o mesmo tipo de comprimento variável, nulidade e nomes de coluna:

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT b FROM t1;
ELSE
    SELECT d FROM t2;';

Este é um conjunto de resultados parcial.

Coluna Valor
name Nome da coluna desconhecido
system_type_name varchar
max_length 20
is_nullable 1

Nome de coluna forçado a ser idêntico via alias

Igual ao anterior, mas as colunas têm o mesmo nome via alias de coluna.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT b FROM t1;
ELSE
    SELECT d AS b FROM t2;';

Este é um conjunto de resultados parcial.

Coluna Valor
name b
system_type_name varchar
max_length 20
is_nullable 1

Erro porque os tipos de coluna não podem ser correspondidos

Os tipos de coluna diferem nos primeiros possíveis conjuntos de resultados diferentes.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    SELECT b FROM t1;
ELSE
    SELECT c FROM t1;';

Isso resulta em um erro de tipos incompatíveis (varchar(10) vs. nvarchar(10)).

O conjunto de resultados pode retornar um erro

O primeiro conjunto de resultados é erro ou conjunto de resultados.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    RAISERROR(''Some Error'', 16 , 1);
ELSE
    SELECT a FROM t1;
SELECT e FROM t2; -- Ignored, not a possible first result set.';

Este é um conjunto de resultados parcial.

Coluna Valor
name a
system_type_name int
is_nullable 1

Alguns caminhos de código não retornam resultados

O primeiro conjunto de resultados é nulo ou um conjunto de resultados.

EXEC sp_describe_first_result_set @tsql = N'
IF (1 = 1)
    RETURN;
SELECT a FROM t1;';

Este é um conjunto de resultados parcial.

Coluna Valor
name a
system_type_name int
is_nullable 1

Resultado do SQL dinâmico

O primeiro conjunto de resultados é SQL dinâmico que pode ser descoberto porque é uma cadeia de caracteres literal.

EXEC sp_describe_first_result_set @tsql = N'
EXEC(N''SELECT a FROM t1'');';

Este é um conjunto de resultados parcial.

Coluna Valor
name a
system_type_name int
is_nullable 1

Falha no resultado do SQL dinâmico

O primeiro conjunto de resultados é indefinido devido ao SQL dinâmico.

EXEC sp_describe_first_result_set @tsql = N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
    SET @SQL += N'' AND e > 10'';
EXEC(@SQL);';

Isso resulta em um erro. O resultado não pode ser descoberto devido ao SQL dinâmico.

Conjunto de resultados especificado por usuário

O primeiro conjunto de resultados é especificado manualmente pelo usuário.

EXEC sp_describe_first_result_set @tsql =
N'
DECLARE @SQL NVARCHAR(max);
SET @SQL = N''SELECT a FROM t1 WHERE 1 = 1'';
IF (1 = 1)
    SET @SQL += N'' AND e > 10'';
EXEC(@SQL)
    WITH RESULT SETS (
        (Column1 BIGINT NOT NULL)
    );';

Este é um conjunto de resultados parcial.

Coluna Valor
name Column1
system_type_name bigint
is_nullable 0

Erro causado por um conjunto de resultados ambíguo

Este exemplo pressupõe que outro usuário nomeado user1 tenha uma tabela nomeada t1 no esquema s1 padrão com colunas (a int NOT NULL).

EXEC sp_describe_first_result_set @tsql = N'
    IF (@p > 0)
    EXECUTE AS USER = ''user1'';
    SELECT * FROM t1;',
@params = N'@p int';

Esse código resulta em um Invalid object name erro. t1 pode ser um ou dbo.t1 s1.t1, cada um com um número diferente de colunas.

Resulta até mesmo com um conjunto de resultados ambíguo

Use as mesmas suposições do exemplo anterior.

EXEC sp_describe_first_result_set @tsql =
N'
    IF (@p > 0)
    EXECUTE AS USER = ''user1'';
    SELECT a FROM t1;';

Este é um conjunto de resultados parcial.

Coluna Valor
name a
system_type_name int
is_nullable 1

Ambos dbo.t1.a e s1.t1.a têm tipo int e nulidade diferente.