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