Partilhar via


sp_describe_first_result_set (Transact-SQL)

Aplica-se a:SQL ServerBanco de Dados SQL do AzureInstância Gerenciada SQL do AzureAzure Synapse AnalyticsAnalytics Platform System (PDW)ponto de extremidade de análise SQL no Microsoft FabricWarehouse no Microsoft Fabric

Retorna os metadados para o primeiro conjunto de resultados possível do lote de Transact-SQL. Retorna um conjunto de resultados vazio se o lote não retornar nenhum resultado. 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.

Transact-SQL convenções de sintaxe

Sintaxe

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

Argumentos

Importante

Os argumentos para procedimentos armazenados estendidos devem ser inseridos na ordem específica, conforme descrito na seção de sintaxe. Se os parâmetros forem inseridos fora de ordem, ocorrerá uma mensagem de erro.

[ @tsql = ] 'tsql'

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

[ @params = ] N'@parameter_namedata_type [ , ... n

@params fornece uma cadeia de caracteres de declaração para parâmetros para o lote Transact-SQL, que é semelhante a 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 incorporados 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âmetros adicionais. Cada parâmetro especificado na instrução deve ser definido em @params. Se a instrução Transact-SQL ou 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 extra e informações da tabela de origem são retornadas. Se definido como 1, cada consulta é analisada como se incluísse uma opção FOR BROWSE na consulta.

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

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

  • Se definido como 2, cada consulta é 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 de código de retorno

sp_describe_first_result_set sempre retorna um status de zero no sucesso. Se o procedimento gerar um erro e o procedimento for chamado de 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 a partir do Transact-SQL, o valor de retorno será sempre zero, mesmo quando houver um erro.

Conjunto de resultados

Esses 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 anulabilidade 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 pouco Indica que a coluna é uma coluna extra adicionada para fins de informações de navegação e que ela realmente não aparece no conjunto de resultados. Não anulável.
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 anulável.
name sysname Contém o nome da coluna se um nome puder ser determinado. Caso contrário, contém NULL. Nulo.
is_nullable pouco 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 anulável.
system_type_id int Contém a system_type_id do tipo de dados da coluna, conforme especificado em sys.types. Para tipos CLR, embora a coluna system_type_name retorne NULL, essa coluna retorna o valor 240. Não anulável.
system_type_name nvarchar(256) Contém o nome e os 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. Nulo.
max_length pequeno Comprimento máximo (em bytes) da coluna.

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

Para texto colunas, o valor max_length é 16 ou o valor definido por sp_tableoption 'text in row'. Não anulável.
precision minúsculo Precisão da coluna, se for de base numérica. Caso contrário, retorna 0. Não anulável.
scale minúsculo Escala da coluna, se baseada em números. Caso contrário, retorna 0. Não anulável.
collation_name sysname Nome do agrupamento da coluna, se baseado em caracteres. Caso contrário, retorna NULL. Nulo.
user_type_id int Para tipos CLR e alias, contém o user_type_id do tipo de dados da coluna, conforme especificado em sys.types. Caso contrário, é NULL. Nulo.
user_type_database sysname Para tipos CLR e alias, contém o nome do banco de dados no qual o tipo está definido. Caso contrário, é NULL. Nulo.
user_type_schema sysname Para CLR e tipos de alias, contém o nome do esquema no qual o tipo é definido. Caso contrário, é NULL. Nulo.
user_type_name sysname Para CLR e tipos de alias, contém o nome do tipo. Caso contrário, é NULL. Nulo.
assembly_qualified_type_name nvarchar(4000) Para tipos CLR, retorna o nome do assembly e a classe que define o tipo. Caso contrário, é NULL. Nulo.
xml_collection_id int Contém a xml_collection_id do tipo de dados da coluna, conforme especificado em sys.columns. Esta coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquema XML. Nulo.
xml_collection_database sysname Contém o banco de dados no qual a coleção de esquema XML associada a esse tipo é definida. Esta coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquema XML. Nulo.
xml_collection_schema sysname Contém o esquema no qual a coleção de esquema XML associada a esse tipo é definida. Esta coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquema XML. Nulo.
xml_collection_name sysname Contém o nome da coleção de esquema XML associada a esse tipo. Esta coluna retornará NULL se o tipo retornado não estiver associado a uma coleção de esquema XML. Nulo.
is_xml_document pouco 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, retorna 0. Não anulável.
is_case_sensitive pouco 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 anulável.
is_fixed_length_clr_type pouco Retorna 1 se a coluna for um tipo CLR de comprimento fixo e 0 se não for. Não anulável.
source_server sysname Nome do servidor de origem retornado pela coluna neste resultado (se for originário de um servidor remoto). O nome é dado como aparece em sys.servers. Retorna NULL se a coluna se origina no servidor local ou se não é possível determinar em qual servidor ela se origina. Só é preenchido se forem solicitadas informações de navegação. Nulo.
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. Só é preenchido se forem solicitadas informações de navegação. Nulo.
source_schema sysname Nome do esquema de origem retornado pela coluna neste resultado. Retorna NULL se o esquema não puder ser determinado. Só é preenchido se forem solicitadas informações de navegação. Nulo.
source_table sysname Nome da tabela de origem retornada pela coluna neste resultado. Retorna NULL se a tabela não puder ser determinada. Só é preenchido se forem solicitadas informações de navegação. Nulo.
source_column sysname Nome da coluna de origem retornada pela coluna de resultados. Retorna NULL se a coluna não puder ser determinada. Só é preenchido se forem solicitadas informações de navegação. Nulo.
is_identity_column pouco 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. Nulo.
is_part_of_unique_key pouco 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. Preenchido apenas se forem solicitadas informações de navegação. Nulo.
is_updateable pouco 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. Nulo.
is_computed_column pouco Retorna 1 se a coluna for uma coluna calculada e 0 se não. Retorna NULL se não for possível determinar que a coluna é uma coluna calculada. Nulo.
is_sparse_column_set pouco 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. Nulo.
ordinal_in_order_by_list pequeno Posição desta coluna na ORDER BY lista. Retorna NULL se a coluna não aparecer na lista de ORDER BY ou se a lista de ORDER BY não puder ser determinada exclusivamente. Nulo.
order_by_list_length pequeno Comprimento da lista de ORDER BY. Retorna NULL se não houver nenhuma lista ORDER BY ou se a lista de ORDER BY não puder ser determinada exclusivamente. Esse valor é o mesmo para todas as linhas retornadas por sp_describe_first_result_set. Nulo.
order_by_is_descending pequeno Se o ordinal_in_order_by_list não estiver NULL, a coluna order_by_is_descending informa a direção da cláusula ORDER BY para esta coluna. Caso contrário, informa NULL. Nulo.
tds_type_id int Para uso interno. Não anulável.
tds_length int Para uso interno. Não anulável.
tds_collation_id int Para uso interno. Nulo.
tds_collation_sort_id minúsculo Para uso interno. Nulo.

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 então 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 anulabilidade e o tipo de dados podem ser diferentes. 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 o momento em que sp_describe_first_result_set é chamado e o momento 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 de Transact-SQL válido. A validade é determinada pela análise e análise do lote 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.

  • A entrada Transact-SQL lote declara uma variável local do 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 é consultada.

Se todas as outras verificações forem bem-sucedidas, todos os caminhos de fluxo de controle possíveis dentro do lote de entrada serão considerados. Isso leva em consideração todas as instruções de fluxo de controle (blocosGOTO, IF/ELSE, WHILEe Transact-SQL TRY/CATCH), bem como quaisquer procedimentos, lotes de Transact-SQL dinâmicos ou gatilhos invocados do lote de entrada por uma instrução EXEC, uma instrução DDL que faz com que gatilhos DDL sejam acionados ou uma instrução DML que faz com que gatilhos sejam disparados em uma tabela de destino ou em uma tabela que é 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 várias instruções iniciais possíveis são encontradas em um lote, seus resultados podem diferir em número de colunas, nome da coluna, anulabilidade e tipo de dados. Como essas diferenças são tratadas é descrito com mais detalhes aqui:

  • Se o número de colunas for diferente, um erro será lançado e nenhum resultado será retornado.

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

  • Se a anulabilidade diferir, a anulabilidade retornada permitirá NULL.

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

    • varchar(a) a varchar(a') onde a' > a.
    • varchar(a) a varchar(max)
    • nvarchar(a) para nvarchar(a') onde a' > a.
    • nvarchar(a) para nvarchar(max)
    • varbinary(a) para varbinary(a') onde a' > a.
    • varbinary(a) a varbinary(max)

sp_describe_first_result_set não suporta recursão indireta.

Permissões

Requer permissão para executar o argumento @tsql.

Exemplos

Exemplos típicos

Um. 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 seguintes ilustram a principal diferença entre os diferentes modos de informação de navegação. Apenas 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;

Aqui está um conjunto de resultados parciais.

is_hidden column_ordinal Designação source_schema source_table source_column is_part_of_unique_key
0 1 b3 NULL NULL NULL NULL

Exemplo usando 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;

Aqui está um conjunto de resultados parciais.

is_hidden column_ordinal Designação 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;

Aqui está o conjunto de resultados.

is_hidden column_ordinal Designação 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 numa tabela

Em alguns cenários, você precisa colocar os resultados do procedimento sp_describe_first_result_set em uma tabela para que você 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ê pode 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 instruções a seguir 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 em 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 em diferentes conjuntos possíveis de primeiros resultados.

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 em possíveis primeiros conjuntos de resultados diferem por comprimento para o mesmo tipo de comprimento variável, anulabilidade e nomes de coluna:

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

Aqui está um conjunto de resultados parciais.

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

Nome da coluna forçado a ser idêntico através de aliasing

O mesmo que o anterior, mas as colunas têm o mesmo nome através do aliasing de coluna.

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

Aqui está um conjunto de resultados parciais.

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 colunas diferem em diferentes conjuntos possíveis de primeiros resultados.

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 é um erro ou um 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.';

Aqui está um conjunto de resultados parciais.

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;';

Aqui está um conjunto de resultados parciais.

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'');';

Aqui está um conjunto de resultados parciais.

Coluna Valor
name a
system_type_name int
is_nullable 1

Falha de 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 pelo 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)
    );';

Aqui está um conjunto de resultados parciais.

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 chamado user1 tenha uma tabela chamada t1 no esquema padrão s1 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 erro de Invalid object name. t1 pode ser dbo.t1 ou s1.t1, cada uma com um número diferente de colunas.

Resultado 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;';

Aqui está um conjunto de resultados parciais.

Coluna Valor
name a
system_type_name int
is_nullable 1

Tanto dbo.t1.a quanto s1.t1.a têm tipo inte anulabilidade diferente.