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 do SQL 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'@parameter_name data_type [ , ... 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'@parameter_name data_type [ , ... n ]'
@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 umaFOR 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 NULL e 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
, WHILE
e blocos Transact-SQL/TRY
CATCH
), 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;
Veja a seguir 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.