Compartir a través de


sp_describe_first_result_set (Transact-SQL)

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

Icono de vínculo a temas Convenciones de sintaxis de Transact-SQL

Sintaxis

sp_describe_first_result_set [ @tsql = ] N'Transact-SQL_batch' 
    [ , [ @params = ] N'parameters' ] 
    [ , [ @browse_information_mode = ] <tinyint> ] ]

Argumentos

  • [ @tsql = ] 'Transact-SQL_batch'
    Una o varias instrucciones Transact-SQL. Transact-SQL_batch  puede ser de tipo nvarchar(n) o nvarchar(max).

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

    Se trata de una cadena que contiene las definiciones de todos los parámetros que se han incrustado en Transact-SQL_batch. 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 el lote o la instrucción de Transact-SQL no contiene parámetros, no es necesario el uso de @params. NULL es el valor predeterminado para este parámetro.

  • [ @browse_information_mode = ] tinyint
    Especifica si se devuelven columnas de clave adicionales e información de la tabla de origen. Si está establecido en 1, cada consulta se analiza como si incluyera una opción FOR BROWSE. Se devuelven las columnas de clave adicionales e información de la tabla de origen.

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

    • Si está establecido en 1, cada consulta se analiza como si incluyera una opción FOR BROWSE. Esto devolverá los nombres de tabla base como información de la columna de origen.

    • Si se establece en 2, cada consulta se analiza como si se fuera a usar en la preparación o ejecución de un cursor. Esto devolverá los nombres de vista como información de la columna de origen.

Valores de código de retorno

sp_describe_first_result_set siempre devuelve un estado de cero si se ejecuta correctamente. Si el procedimiento produce un error y se llama al procedimiento como RPC, el estado de retorno se rellena con 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.

Conjuntos 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 en cada una de las rutas de acceso de control, se devuelve un conjunto de resultados con cero filas.

Nombre de columna

Tipo de datos

Descripción

is_hidden

bit NOT NULL

Indica que la columna es una columna adicional agregada para examinar el propósito de la información y que no aparece realmente en el conjunto de resultados.

column_ordinal

int NOT NULL

Contiene la posición ordinal de la columna en el conjunto de resultados. La posición de la primera columna se especificará como 1.

name

sysname NULL

Contiene el nombre de la columna si se puede determinar uno. De lo contrario, contendrá NULL.

is_nullable

bit NOT NULL

Contiene el valor 1 si la columna permite valores NULL, 0 si la columna no permite valores NULL y 1 si no se puede determinar si la columna permite valores NULL.

system_type_id

int NOT NULL

Contiene el system_type_id del tipo de datos de la columna tal y como se especifica en sys.types. En el caso de los tipos de CLR, aunque la columna system_type_name devuelva NULL, esta columna devolverá el valor 240.

system_type_name

nvarchar(256) NULL

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 de CLR, NULL se devuelve en esta columna.

max_length

smallint NOT NULL

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 tipo text, el valor de max_length será 16 o el valor establecido por sp_tableoption 'text in row'.

precision

tinyint NOT NULL

Precisión de la columna, si está basada en números. De lo contrario, devuelve 0.

scale

tinyint NOT NULL

La escala de la columna se basa en valores numéricos. De lo contrario, devuelve 0.

collation_name

sysname NULL

Nombre de la intercalación de la columna, si está basada en caracteres. De lo contrario, devuelve NULL.

user_type_id

int NULL

Para los tipos de alias y CLR, contiene el user_type_id del tipo de datos de la columna tal y como se especifica en sys.types. De lo contrario, es NULL.

user_type_database

sysname NULL

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.

user_type_schema

sysname NULL

Para los tipos de alias y CLR, contiene el nombre del esquema en el que se define el tipo. De lo contrario, es NULL.

user_type_name

sysname NULL

Para los tipos de alias y CLR, contiene el nombre del tipo. De lo contrario, es 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.

xml_collection_id

int NULL

Contiene el xml_collection_id del tipo de datos de la columna tal y como se especifica en sys.columns. Esta columna devolverá NULL si el tipo devuelto no está asociado a una colección de esquema XML.

xml_collection_database

sysname NULL

Contiene la base de datos en la que se define la colección de esquema XML asociado a este tipo. Esta columna devolverá NULL si el tipo devuelto no está asociado a una colección de esquema XML.

xml_collection_schema

sysname NULL

Contiene el esquema en el que se define la colección de esquema XML asociado a este tipo. Esta columna devolverá NULL si el tipo devuelto no está asociado a una colección de esquema XML.

xml_collection_name

sysname NULL

Contiene el nombre de la colección de esquema XML asociado a este tipo. Esta columna devolverá NULL si el tipo devuelto no está asociado a una colección de esquema XML.

is_xml_document

bit NOT NULL

Devuelve 1 si el tipo de datos devuelto es XML y se garantiza que ese tipo es un documento XML completo (incluido un nodo raíz), en lugar de un fragmento XML. De lo contrario, devuelve 0.

is_case_sensitive

bit NOT NULL

Devuelve 1 si la columna es un tipo de cadena que distingue entre mayúsculas y minúsculas, y 0 si no lo es.

is_fixed_length_clr_type

bit NOT NULL

Devuelve 1 si la columna es de un tipo CLR de longitud fija y 0 de lo contrario.

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 proporciona tal y 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.

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.

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.

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.

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.

is_identity_column

bit NULL

Devuelve 1 si la columna es una columna de identidad y 0 de lo contrario. Devuelve NULL si no se puede determinar que la columna es una columna de identidad.

is_part_of_unique_key

bit NULL

Devuelve 1 si la columna forma parte de un índice único (que incluye una restricción única y principal) y 0 de lo contrario. 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.

is_updateable

bit NULL

Devuelve 1 si la columna es actualizable y 0 de lo contrario. Devuelve NULL si no se puede determinar que la columna se puede actualizar.

is_computed_column

bit NULL

Devuelve 1 si la columna es una columna calculada y 0 en caso contrario. Devuelve NULL si no se puede determinar que la columna es una columna calculada.

is_sparse_column_set

bit NULL

Devuelve 1 si la columna es una columna dispersa y 0 si no lo es. Devuelve NULL si no se puede determinar que la columna forma parte de un conjunto de columnas dispersas.

ordinal_in_order_by_list

smallint NULL

Posición de esta columna en la lista ORDER BY. Devuelve NULL si no aparece en la lista ORDER BY o si la lista ORDER BY no se puede determinar de forma inequívoca.

order_by_list_length

smallint NULL

Longitud de la lista de ORDER BY. Devuelve NULL si no hay ninguna lista ORDER BY o si no se puede determinar la lista ORDER BY singularmente. Observe que este valor será el mismo para todas las filas devueltas por sp_describe_first_result_set.

order_by_is_descending

smallint NULL

Si ordinal_in_order_by_list no es NULL, la columna order_by_is_descending notifica la dirección de la cláusula ORDER BY para esta columna. De lo contrario, notifica NULL.

tds_type_id

int NOT NULL

Para uso interno.

tds_length

int NOT NULL

Para uso interno.

tds_collation_id

int NULL

Para uso interno.

tds_collation_sort_id

tinyint NULL

Para uso interno.

Comentarios

sp_describe_first_result_set garantiza que si el procedimiento devuelve los primeros metadatos del conjunto de resultados para el lote A (hipotético) y si el lote (A) se ejecuta posteriormente, el lote (1) generará un error de tiempo de optimización, (2) generará un error en tiempo de ejecución, (3) no devolverá ningún conjunto de resultados o (4) devolverá un primer conjunto de resultados con los mismos metadatos descritos en 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, existe la garantía de que la ejecución de lotes no devolverá conjuntos de resultados.

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

sp_describe_first_result_set devuelve un error en algunos de los casos siguientes.

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

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

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

  • Si la instrucción utiliza 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 permite tener en cuenta todas las instrucciones de flujo de control (GOTO, IF/ELSE, WHILE y bloques TRY/CATCH de Transact-SQL), así como cualquier procedimiento, lote Transact-SQL dinámico o desencadenador invocado desde el lote de entrada por una instrucción EXEC, una instrucción que active los desencadenadores DDL o una instrucción DML que active los desencadenadores en una tabla de destino o en una tabla que se ha modificado debido a la acción en cascada de una restricción de clave externa. En el caso de que haya numerosas rutas de acceso de control posibles, los algoritmos se detienen en algún punto.

Para cada ruta de flujo de control, la primera instrucción (si existe) que devuelve un conjunto de resultados viene determinada 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 difiere el nombre de columna, el valor devuelto se establece en NULL.

  • Si difiere la nulabilidad, la nulabilidad devuelta permitirá valores NULL.

  • Si difiere el tipo de datos, se generará un error y no se devolverán resultados salvo en los casos siguientes:

    • De varchar(a) a varchar(a') donde a' > a.

    • varchar(a) to varchar(max)

    • De nvarchar(a) a nvarchar(a') donde a' > a.

    • nvarchar(a) to nvarchar(max)

    • De varbinary(a) a varbinary(a') donde a' > a.

    • varbinary(a) to varbinary(max)

sp_describe_first_result_set no admite esta recursividad indirecta.

Permisos

Se requiere permiso para ejecutar el argumento @tsql.

Ejemplos

Ejemplos habituales

A.Ejemplo sencillo

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

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.

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 de modo de exploración

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

El ejemplo que usa 0 indica que no se devuelve información alguna.

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;

El conjunto de resultados es el siguiente.

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

El conjunto de resultados es el siguiente.

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

El ejemplo que usa 2 indica que se analiza como si se estuviera preparando un cursor.

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

El conjunto de resultados es el siguiente.

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

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.

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.

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

Resultado: Error, tipos no coincidentes (intfrente a smallint).

El nombre de columna no se puede determinar

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.

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

Resultado: <Nombre de columna desconocido> varchar(20) NULL

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.

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

Resultado: b varchar(20) NULL

Error porque los tipos de columna no coinciden

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

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

Resultado: Error, tipos no coincidentes (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.

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

Resultado: a int NULL

Algunas rutas de acceso del código no devuelven resultados

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

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

Resultado: a int NULL

Resultado de SQL dinámico

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

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

Resultado: a INT NULL

Error al obtener resultados de SQL dinámico

El primer conjunto de resultados no está definido debido a un SQL dinámico.

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

Resultado: Error. El resultado no se puede detectar debido a un SQL dinámico.

Conjunto de resultados especificado por el usuario

El usuario especifica manualmente el primer conjunto de resultados.

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

Resultado: Column1 bigint NOT NULL

Error generado por un conjunto de resultados ambiguo

En este ejemplo se supone que otro usuario denominado usuario1 tiene una tabla denominada t1 en el esquema predeterminado s1 con columnas (int NOT NULL).

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

Resultado: Error. t1 puede ser dbo.t1 o s1.t1, cada uno con un número de columnas diferente.

Resultado incluso con el conjunto de resultados ambiguo

Use las mismas suposiciones que en el ejemplo anterior.

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

Resultado: a int NULL porque dbo.t1.a y s1.t1.a tienen el tipo int y diferente nulabilidad.

Vea también

Referencia

sp_describe_undeclared_parameters (Transact-SQL)

sys.dm_exec_describe_first_result_set (Transact-SQL)

sys.dm_exec_describe_first_result_set_for_object (Transact-SQL)