sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo redefinir las columnas devueltas por un procedimiento almacenado en SQL Server

Cuando ejecuta un procedimiento almacenado que devuelve un conjunto de resultados en SQL Server, las columnas devueltas se definen en el procedimiento almacenado.

Pero, ¿sabía que puede redefinir esas columnas?

Lo que quiero decir es que puede cambiar los nombres y/o el tipo de datos de las columnas devueltas en el conjunto de resultados.

Esto podría ahorrarle tener que jugar con los encabezados de columna y los formatos de datos en caso de que necesite usar ese conjunto de resultados en otra configuración.

Por ejemplo, si un procedimiento almacenado devuelve un datetime2 columna, pero solo necesita la parte de la fecha, puede especificar fecha para esa columna, y su conjunto de resultados solo incluirá la parte de la fecha.

Y lo mejor es que puedes hacerlo como parte de EXECUTE declaración. No es necesario masajear los datos después de ejecutar el procedimiento. La forma de hacerlo es usando WITH RESULT SETS cláusula del EXECUTE declaración.

Ejemplo

Aquí hay un ejemplo para demostrar cómo usar WITH RESULT SETS cláusula para cambiar los nombres de las columnas y los tipos de datos del conjunto de resultados de un procedimiento almacenado.

Resultados sin procesar

Primero, veamos los resultados sin procesar de un procedimiento almacenado.

EXEC sp_getCityById @CityId = 1;

Resultado:

+------------+----------------------------+-----------------------------+
| CityName   | LatestRecordedPopulation   | ValidFrom                   |
|------------+----------------------------+-----------------------------|
| Aaronsburg | 613                        | 2013-01-01 00:00:00.0000000 |
+------------+----------------------------+-----------------------------+

Según nuestros requisitos, es posible que deseemos que el procedimiento no utilice un encabezado de columna tan largo para la población (LatestRecordedPopulation ).

También podríamos desear que ValidFrom La columna no incluyó la parte del tiempo, ya que ocupa espacio innecesario y no es importante para nuestro propósito particular.

También es posible que deseemos presentar los encabezados de las columnas con un espacio, solo para que se vea un poco más presentable para quien sea a quien se lo enviaremos.

Redefinir las columnas

Ahora sigamos adelante y usemos WITH RESULT SETS cláusula para redefinir las columnas.

EXEC sp_getCityById @CityId = 1
WITH RESULT SETS   
(  
    (
        [City] nvarchar(50),
        [Population] int,
        [Valid From] date
    )
);

Resultado:

+------------+--------------+--------------+
| City       | Population   | Valid From   |
|------------+--------------+--------------|
| Aaronsburg | 613          | 2013-01-01   |
+------------+--------------+--------------+

Entonces, usando WITH RESULT SETS cláusula, pudimos cambiar los nombres de las columnas y el tipo de datos.

De hecho, en este ejemplo cambié el tipo de datos de las últimas dos columnas de bigint a int y desde datetime2(7) hasta la fecha , respectivamente.

Analizar los conjuntos de resultados

Podemos usar vistas de administración dinámicas como sys.dm_exec_describe_first_result_set y sys.dm_exec_describe_first_result_set_for_object para averiguar los tipos de datos reales de cada conjunto de resultados.

Aquí hay un ejemplo del uso de sys.dm_exec_describe_first_result_set_for_object para obtener los nombres de las columnas y sus respectivos tipos de datos devueltos por el procedimiento almacenado.

SELECT 
    name,
    system_type_name,
    max_length,
    [precision],
    scale,
    user_type_name
FROM sys.dm_exec_describe_first_result_set_for_object(OBJECT_ID('sp_getCityById'), 0);

Resultado:

+--------------------------+--------------------+--------------+-------------+---------+------------------+
| name                     | system_type_name   | max_length   | precision   | scale   | user_type_name   |
|--------------------------+--------------------+--------------+-------------+---------+------------------|
| CityName                 | nvarchar(50)       | 100          | 0           | 0       | NULL             |
| LatestRecordedPopulation | bigint             | 8            | 19          | 0       | NULL             |
| ValidFrom                | datetime2(7)       | 8            | 27          | 7       | NULL             |
+--------------------------+--------------------+--------------+-------------+---------+------------------+

Estos son los nombres de columna y tipos de datos reales devueltos en el conjunto de resultados (sin redefinir nada).

Podemos ver que las dos últimas columnas son bigint y fecha y hora2(7) respectivamente.

Ahora usemos sys.dm_exec_describe_first_result_set para obtener los metadatos de nuestra consulta modificada.

SELECT 
    name,
    system_type_name,
    max_length,
    [precision],
    scale,
    user_type_name
FROM sys.dm_exec_describe_first_result_set(
    'EXEC sp_getCityById @CityId = 1
        WITH RESULT SETS   
        (  
            (
                [City] nvarchar(50),
                [Population] int,
                [Valid To] date
            )
        );', 
        null, 
        0
    );

Resultado:

+------------+--------------------+--------------+-------------+---------+------------------+
| name       | system_type_name   | max_length   | precision   | scale   | user_type_name   |
|------------+--------------------+--------------+-------------+---------+------------------|
| City       | nvarchar(50)       | 100          | 0           | 0       | NULL             |
| Population | int                | 4            | 10          | 0       | NULL             |
| Valid To   | date               | 3            | 10          | 0       | NULL             |
+------------+--------------------+--------------+-------------+---------+------------------+

Entonces podemos ver que los nombres de las columnas han cambiado, y los tipos de datos de las últimas dos columnas también han cambiado como se especifica.

Conjuntos de resultados múltiples

Algunos procedimientos almacenados devuelven varios conjuntos de resultados. Al usar WITH RESULT SETS en estos procedimientos, debe asegurarse de incluir definiciones para cada conjunto de resultados.

No puedes simplemente redefinir algunos pero no los otros. Si haces eso, obtendrás un error.

Si solo necesita redefinir un conjunto de resultados, debe hacerlos todos, incluso si sus definiciones siguen siendo las mismas que su definición original.

Al hacer esto, separe cada definición con una coma.

Conjuntos de resultados originales

El siguiente procedimiento devuelve tres conjuntos de resultados.

EXEC sp_getCityStateCountryByCityId @CityId = 1;

Resultado:

+------------+----------------------------+-----------------------------+
| CityName   | LatestRecordedPopulation   | ValidFrom                   |
|------------+----------------------------+-----------------------------|
| Aaronsburg | 613                        | 2013-01-01 00:00:00.0000000 |
+------------+----------------------------+-----------------------------+
(1 row affected)
+---------------------+---------------------+----------------------------+
| StateProvinceCode   | StateProvinceName   | LatestRecordedPopulation   |
|---------------------+---------------------+----------------------------|
| PA                  | Pennsylvania        | 13284753                   |
+---------------------+---------------------+----------------------------+
(1 row affected)
+-----------------+---------------+----------------------------+
| IsoAlpha3Code   | CountryName   | LatestRecordedPopulation   |
|-----------------+---------------+----------------------------|
| USA             | United States | 313973000                  |
+-----------------+---------------+----------------------------+
(1 row affected)

Conjuntos de resultados redefinidos

Podemos redefinir estos conjuntos de resultados con el siguiente código.

EXEC sp_getCityStateCountryByCityId @CityId = 1
WITH RESULT SETS   
(  
    (
        [City] nvarchar(50),
        [Population] int,
        [Valid From] date
    ),
    (
        [State Code] nvarchar(5),
        [State Name] nvarchar(50),
        [Population] int
    ),
    (
        [Country Code] nvarchar(3),
        [Country Name] nvarchar(60),
        [Population] int
    )
);

Resultado:

+------------+--------------+--------------+
| City       | Population   | Valid From   |
|------------+--------------+--------------|
| Aaronsburg | 613          | 2013-01-01   |
+------------+--------------+--------------+
(1 row affected)
+--------------+--------------+--------------+
| State Code   | State Name   | Population   |
|--------------+--------------+--------------|
| PA           | Pennsylvania | 13284753     |
+--------------+--------------+--------------+
(1 row affected)
+----------------+----------------+--------------+
| Country Code   | Country Name   | Population   |
|----------------+----------------+--------------|
| USA            | United States  | 313973000    |
+----------------+----------------+--------------+
(1 row affected)

Reducción del número de columnas devueltas por el procedimiento almacenado

Cuando me enteré por primera vez de WITH RESULT SETS cláusula, estaba emocionado, porque pensé que proporcionaría una manera simple de reducir la cantidad de columnas devueltas por el procedimiento almacenado.

Lamentablemente, ese no es el caso.

Si no incluye todas las columnas devueltas por el procedimiento almacenado en su WITH RESULT SETS cláusula, obtendrá un error.

Sin embargo, no todo está perdido. Consulte Cómo seleccionar un subconjunto de columnas de un procedimiento almacenado si desea menos columnas de las que devuelve el procedimiento.