Compartir vía


sp_describe_first_result_set (Transact-SQL)

Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Punto de conexión de análisis SQL en Microsoft Fabric Almacenamiento en Microsoft Fabric

Devuelve los metadatos del primer conjunto de resultados posible del lote de Transact-SQL. Devuelve un conjunto de resultados vacío si el lote no devuelve resultados. Genera un error si el Motor de base de datos no puede determinar los metadatos de la primera consulta que se ejecutará realizando un análisis estático. La vista de administración dinámica sys.dm_exec_describe_first_result_set devuelve la misma información.

Convenciones de sintaxis de Transact-SQL

Sintaxis

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

Argumentos

[ @tsql = ] 'tsql'

Una o varias instrucciones Transact-SQL. @tsql puede ser nvarchar(n) o nvarchar(max).

[ @params = ] N'@parameter_name data_type [ , ... n ]'

@params proporciona una cadena de declaración para los parámetros del lote de Transact-SQL, que es similar a sp_executesql. Los parámetros pueden ser nvarchar(n) o nvarchar(max).

Cadena que contiene las definiciones de todos los parámetros incrustados en @tsql. La cadena debe ser una constante Unicode o una variable Unicode. Cada definición de parámetro se compone de un nombre de parámetro y un tipo de datos. n es un marcador de posición que indica definiciones de parámetros adicionales. Todos los parámetros especificados en la instrucción deben definirse en @params. Si la instrucción Transact-SQL o el lote de la instrucción no contiene parámetros, no se requiere @params . NULL es el valor predeterminado de este parámetro.

[ @browse_information_mode = ] tinyint

Especifica si se devuelven columnas de clave adicionales y información de la tabla de origen. Si se establece en 1, cada consulta se analiza como si incluye una FOR BROWSE opción en la consulta.

  • Si se establece en 0, no se devuelve información.

  • Si se establece en 1, cada consulta se analiza como si incluye una FOR BROWSE opción en la consulta. Esto devuelve nombres de tabla base como información de columna de origen.

  • Si se establece 2en , cada consulta se analiza como si se usara para preparar o ejecutar un cursor. Esto devuelve nombres de vista como información de columna de origen.

Valores de código de retorno

sp_describe_first_result_set siempre devuelve un estado de cero si se realiza correctamente. Si el procedimiento produce un error y se llama al procedimiento como RPC, el estado devuelto se rellena mediante el tipo de error descrito en la columna error_type de sys.dm_exec_describe_first_result_set. Si se llama al procedimiento desde Transact-SQL, el valor devuelto siempre es cero, incluso cuando se produce un error.

Conjunto de resultados

Estos metadatos comunes se devuelven como un conjunto de resultados con una única fila por cada columna de los metadatos de los resultados. Cada fila describe el tipo y la nulabilidad de la columna en el formato descrito en la siguiente sección. Si la primera instrucción no existe para cada ruta de acceso de control, se devuelve un conjunto de resultados con cero filas.

Nombre de la columna Tipo de datos Descripción
is_hidden bit Indica que la columna es una columna adicional agregada para fines de información de exploración y que realmente no aparece en el conjunto de resultados. No acepta valores NULL.
column_ordinal int Contiene la posición ordinal de la columna en el conjunto de resultados. La posición de la primera columna se especifica como 1. No acepta valores NULL.
name sysname Contiene el nombre de la columna si se puede determinar uno. De lo contrario, contiene NULL. Acepta valores NULL.
is_nullable bit Contiene el valor 1 si la columna permite , 0 si la columna no permite NULLNULLy 1 si no se puede determinar si la columna permite NULL. No acepta valores NULL.
system_type_id int Contiene el system_type_id del tipo de datos de la columna tal como se especifica en sys.types. En el caso de los tipos CLR, aunque la system_type_name columna devuelve NULL, esta columna devuelve el valor 240. No acepta valores NULL.
system_type_name nvarchar(256) Contiene el nombre y los argumentos (como length, precision y scale) especificados para el tipo de datos de la columna. Si el tipo de datos es un tipo de alias definido por el usuario, el tipo de sistema subyacente se especifica aquí. Si es un tipo definido por el usuario clR, NULL se devuelve en esta columna. Acepta valores NULL.
max_length smallint Longitud máxima de la columna, en bytes.

-1 = El tipo de datos de columna es varchar(max), nvarchar(max), varbinary(max)o xml.

Para las columnas de texto , el max_length valor es 16 o el valor establecido por sp_tableoption 'text in row'. No acepta valores NULL.
precision tinyint Precisión de la columna, si está basada en números. De lo contrario, devuelve 0. No acepta valores NULL.
scale tinyint La escala de la columna se basa en valores numéricos. De lo contrario, devuelve 0. No acepta valores NULL.
collation_name sysname Nombre de la intercalación de la columna, si está basada en caracteres. De lo contrario, devuelve NULL. Acepta valores NULL.
user_type_id int Para los tipos clR y alias, contiene el user_type_id del tipo de datos de la columna tal como se especifica en sys.types. De lo contrario, es NULL. Acepta valores NULL.
user_type_database sysname Para los tipos de alias y CLR, contiene el nombre de la base de datos en la que se define el tipo. De lo contrario, es NULL. Acepta valores NULL.
user_type_schema sysname Para los tipos de alias y CLR, contiene el nombre del esquema en el que se define el tipo. De lo contrario, es NULL. Acepta valores NULL.
user_type_name sysname Para los tipos de alias y CLR, contiene el nombre del tipo. De lo contrario, es NULL. Acepta valores NULL.
assembly_qualified_type_name nvarchar(4000) Para los tipos CLR, devuelve el nombre del ensamblado y la clase que definen el tipo. De lo contrario, es NULL. Acepta valores NULL.
xml_collection_id int Contiene el xml_collection_id del tipo de datos de la columna tal como se especifica en sys.columns. Esta columna devuelve NULL si el tipo devuelto no está asociado a una colección de esquemas XML. Acepta valores NULL.
xml_collection_database sysname Contiene la base de datos en la que se define la colección de esquema XML asociado a este tipo. Esta columna devuelve NULL si el tipo devuelto no está asociado a una colección de esquemas XML. Acepta valores NULL.
xml_collection_schema sysname Contiene el esquema en el que se define la colección de esquema XML asociado a este tipo. Esta columna devuelve NULL si el tipo devuelto no está asociado a una colección de esquemas XML. Acepta valores NULL.
xml_collection_name sysname Contiene el nombre de la colección de esquema XML asociado a este tipo. Esta columna devuelve NULL si el tipo devuelto no está asociado a una colección de esquemas XML. Acepta valores NULL.
is_xml_document bit Devuelve 1 si el tipo de datos devuelto es XML y se garantiza que ese tipo sea un documento XML completo (incluido un nodo raíz), en lugar de un fragmento XML. De lo contrario, devuelve 0. No acepta valores NULL.
is_case_sensitive bit Devuelve 1 si la columna es un tipo de cadena que distingue mayúsculas de minúsculas y 0 si no lo es. No acepta valores NULL.
is_fixed_length_clr_type bit Devuelve 1 si la columna es un tipo CLR de longitud fija y 0 si no lo es. No acepta valores NULL.
source_server sysname Nombre del servidor de origen que devuelve la columna en este resultado (si se origina desde un servidor remoto). El nombre se asigna tal como aparece en sys.servers. Devuelve NULL si la columna se origina en el servidor local o si no se puede determinar en qué servidor se origina. Solo se rellena si se solicita buscar información. Acepta valores NULL.
source_database sysname Nombre de la base de datos de origen que devuelve la columna en este resultado. Devuelve NULL si no se puede determinar la base de datos. Solo se rellena si se solicita buscar información. Acepta valores NULL.
source_schema sysname Nombre del esquema de origen que devuelve la columna en este resultado. Devuelve NULL si no se puede determinar el esquema. Solo se rellena si se solicita buscar información. Acepta valores NULL.
source_table sysname Nombre de la tabla de origen que devuelve la columna en este resultado. Devuelve NULL si no se puede determinar la tabla. Solo se rellena si se solicita buscar información. Acepta valores NULL.
source_column sysname Nombre de la columna de origen que devuelve la columna de resultado. Devuelve NULL si no se puede determinar la columna. Solo se rellena si se solicita buscar información. Acepta valores NULL.
is_identity_column bit Devuelve 1 si la columna es una columna de identidad y 0 , si no es así. Devuelve NULL si no se puede determinar que la columna es una columna de identidad. Acepta valores NULL.
is_part_of_unique_key bit Devuelve 1 si la columna forma parte de un índice único (incluida la restricción única y principal) y 0 , si no es así. Devuelve NULL si no se puede determinar que la columna forma parte de un índice único. Solo se rellena si se solicita buscar información. Acepta valores NULL.
is_updateable bit Devuelve 1 si la columna se puede actualizar y 0 , si no es así. Devuelve NULL si no se puede determinar que la columna se puede actualizar. Acepta valores NULL.
is_computed_column bit Devuelve 1 si la columna es una columna calculada y 0 , si no es así. Devuelve NULL si no se puede determinar que la columna es una columna calculada. Acepta valores NULL.
is_sparse_column_set bit Devuelve 1 si la columna es una columna dispersa y 0 , si no es así. Devuelve NULL si no se puede determinar que la columna forma parte de un conjunto de columnas dispersas. Acepta valores NULL.
ordinal_in_order_by_list smallint Posición de esta columna en ORDER BY la lista. Devuelve NULL si la columna no aparece en la ORDER BY lista o si la ORDER BY lista no se puede determinar de forma única. Acepta valores NULL.
order_by_list_length smallint Longitud de la ORDER BY lista. Devuelve NULL si no hay ninguna ORDER BY lista o si la ORDER BY lista no se puede determinar de forma única. Este valor es el mismo para todas las filas devueltas por sp_describe_first_result_set. Acepta valores NULL.
order_by_is_descending smallint ordinal_in_order_by_list Si no NULLes , la order_by_is_descending columna informa de la dirección de la ORDER BY cláusula para esta columna. De lo contrario, notifica NULL. Acepta valores NULL.
tds_type_id int Para uso interno. No acepta valores NULL.
tds_length int Para uso interno. No acepta valores NULL.
tds_collation_id int Para uso interno. Acepta valores NULL.
tds_collation_sort_id tinyint Para uso interno. Acepta valores NULL.

Comentarios

sp_describe_first_result_set garantiza que si el procedimiento devuelve los primeros metadatos del conjunto de resultados para (un lote hipotético) A y, si se ejecuta ese lote (A), el lote es:

  • genera un error en tiempo de optimización
  • genera un error en tiempo de ejecución
  • devuelve ningún conjunto de resultados
  • devuelve un primer conjunto de resultados con los mismos metadatos descritos por sp_describe_first_result_set

El nombre, la nulabilidad y el tipo de datos pueden diferir. Si sp_describe_first_result_set devuelve un conjunto de resultados vacío, la garantía es que la ejecución por lotes devuelve conjuntos de resultados sin resultados.

Esta garantía presupone que no hay cambios de esquema importantes en el servidor. Los cambios de esquema pertinentes en el servidor no incluyen la creación de tablas temporales o variables de tabla en el lote A entre el tiempo al que sp_describe_first_result_set se llama y la hora en que se devuelve el conjunto de resultados durante la ejecución, incluidos los cambios de esquema realizados por el lote B.

sp_describe_first_result_set devuelve un error en cualquiera de los casos siguientes:

  • El @tsql de entrada no es un lote válido de Transact-SQL. La validez se determina analizando el lote de Transact-SQL. Los errores causados por el lote durante la optimización de consultas o durante la ejecución no se consideran al determinar si el lote de Transact-SQL es válido.

  • @params no NULL es y contiene una cadena que no es una cadena de declaración sintácticamente válida para los parámetros, o si contiene una cadena que declara cualquier parámetro más de una vez.

  • El lote transact-SQL de entrada declara una variable local con el mismo nombre que un parámetro declarado en @params.

  • La instrucción usa una tabla temporal.

  • La consulta incluye la creación de una tabla permanente que se consulta.

Si todas las demás comprobaciones se realizan correctamente, se tienen en cuenta todas las rutas de flujo de control posibles incluidas en el lote de entrada. Esto tiene en cuenta todas las instrucciones de flujo de control (GOTObloques, IF/ELSE, WHILEy Transact-SQL/TRYCATCH), así como todos los procedimientos, lotes dinámicos de Transact-SQL o desencadenadores invocados desde el lote de entrada por una EXEC instrucción, una instrucción DDL que hace que se activen desencadenadores DDL o una instrucción DML que hace que los desencadenadores se activen en una tabla de destino o en una tabla que se modifique debido a una acción en cascada en una restricción de clave externa. En algún momento, al igual que con muchas rutas de acceso de control posibles, se detiene un algoritmo.

Para cada ruta de acceso de flujo de control, la primera instrucción (si existe) que devuelve un conjunto de resultados viene determinado por sp_describe_first_result_set.

Cuando en el lote se encuentran varias instrucciones que podrían ser las primeras, sus resultados pueden diferir en el número de columnas, el nombre de las columnas, la nulabilidad y el tipo de datos. A continuación se describe con más detalle cómo se administrar estas diferencias:

  • Si el número de columnas difiere, se genera un error y no se devuelve ningún resultado.

  • Si el nombre de columna difiere, el nombre de columna devuelto se establece en NULL.

  • Si la nulabilidad difiere, la nulabilidad devuelta permite NULL.

  • Si el tipo de datos difiere, se produce un error y no se devuelve ningún resultado excepto en los casos siguientes:

    • varchar(a) a varchar(a') donde a' > a.
    • varchar(a) a varchar(max)
    • nvarchar(a) a nvarchar(a') donde a' > a.
    • nvarchar(a) a nvarchar(max)
    • varbinary(a) a varbinary(a') donde a' > a.
    • varbinary(a) a varbinary(max)

sp_describe_first_result_set no admite la recursividad indirecta.

Permisos

Requiere permiso para ejecutar el argumento @tsql .

Ejemplos

Ejemplos típicos

A Ejemplo básico

En el ejemplo siguiente se describe el conjunto de resultados devuelto a partir de una consulta única.

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

En el ejemplo siguiente se muestra el conjunto de resultados devuelto por una única consulta que contiene un 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. Ejemplos del modo examinar

En los tres ejemplos siguientes se muestra la diferencia clave entre los diferentes modos de información de exploración. Solo se incluyen las columnas pertinentes en los resultados de la consulta.

Ejemplo mediante 0, que indica que no se devuelve información.

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;

A continuación se muestra un conjunto parcial de resultados.

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

El ejemplo que usa 1 indica que se devuelve información como si incluyera una opción FOR BROWSE en la consulta.

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

A continuación se muestra un conjunto parcial de resultados.

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 a dbo t a 1

Ejemplo con 2 que indica que se analiza como si estuviera preparando un cursor.

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

Este es el 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. Almacenar los resultados en una tabla

En algunos escenarios, debe colocar los resultados del sp_describe_first_result_set procedimiento en una tabla para que pueda procesar aún más el esquema.

En primer lugar, debe crear una tabla que coincida con la salida del procedimiento 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
);

Al crear una tabla, puede almacenar el esquema de alguna consulta de esa tabla.

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

INSERT INTO #frs
EXEC sys.sp_describe_first_result_set @tsql;

SELECT * FROM #frs;

Ejemplos de problemas

En todos los ejemplos siguientes se usan dos tablas. Ejecute las siguientes instrucciones para crear las tablas de ejemplo.

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

Error porque difiere el número de columnas

En este ejemplo, difiere el número de columnas de los primeros conjuntos de resultados posibles.

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

Error porque difieren los tipos de datos

Los tipos de columnas difieren en los primeros conjuntos de resultados posibles.

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

Esto produce un error de tipos que no coinciden (int frente a smallint).

No se puede determinar el nombre de columna

Las columnas de los primeros conjuntos de resultados posibles difieren en la longitud del mismo tipo de longitud variable, la nulabilidad y los nombres de columna.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name Nombre de columna desconocido
system_type_name varchar
max_length 20
is_nullable 1

Se exige que el nombre de columna sea idéntico en todos los alias

Igual que el caso anterior, pero las columnas tienen el mismo nombre en todos los alias de columna.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name b
system_type_name varchar
max_length 20
is_nullable 1

Error porque no se pueden hacer coincidir los tipos de columna

Los tipos de columnas difieren en los primeros conjuntos de resultados posibles.

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

Esto produce un error de tipos que no coinciden (varchar(10) frente a nvarchar(10)).

El conjunto de resultados puede devolver un error

El primer conjunto de resultados es un error o un 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.';

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name a
system_type_name int
is_nullable 1

Algunas rutas de acceso del código no devuelven resultados

El primer conjunto de resultados es NULL o un conjunto de resultados.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name a
system_type_name int
is_nullable 1

Resultado de SQL dinámico

El primer conjunto de resultados es SQL dinámico que se puede detectar porque es una cadena literal.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name a
system_type_name int
is_nullable 1

Error al obtener resultados de SQL dinámico

El primer conjunto de resultados no está definido debido a un 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);';

Esto produce un error. El resultado no se puede detectar debido a sql dinámico.

Conjunto de resultados especificado por el usuario

El usuario especifica manualmente el primer conjunto de resultados.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name Column1
system_type_name bigint
is_nullable 0

Error causado por un conjunto de resultados ambiguo

En este ejemplo se supone que otro usuario denominado tiene una tabla denominada user1 t1 en el esquema s1 predeterminado con columnas (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';

Este código produce un Invalid object name error. t1 puede ser dbo.t1 o s1.t1, cada uno con un número diferente de columnas.

Resultado incluso con el conjunto de resultados ambiguo

Use las mismas suposiciones que en el ejemplo anterior.

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

A continuación se muestra un conjunto parcial de resultados.

Columna Valor
name a
system_type_name int
is_nullable 1

Tanto dbo.t1.a como s1.t1.a tienen un tipo int y una nulabilidad diferente.