¿Cómo devuelvo los tipos de datos SQL de mi consulta?


Tengo una consulta SQL que consulta una base de datos enorme (como cientos de vistas/tablas con nombres difíciles de leer como CMM-CPP-FAP-ADD) que no necesito ni quiero entender. El resultado de esta consulta debe almacenarse en una tabla provisional para alimentar un informe.

Necesito crear la tabla de ensayo, pero con cientos de vistas/tablas para buscar los tipos de datos que se representan aquí, tengo que preguntarme si hay una mejor manera de construir esta tabla.

Puede ¿alguien me aconseja cómo usaría cualquiera de las herramientas de SQL Server 2008 para adivinar los tipos de datos de origen en mi base de datos SQL 2000?

Como ejemplo general, quiero saber de una consulta como:

SELECT Auth_First_Name, Auth_Last_Name, Auth_Favorite_Number 
FROM Authors

En lugar de los resultados reales, quiero saber que:

Auth_First_Name is char(25)
Auth_Last_Name is char(50)
Auth_Favorite_Number is int

No estoy interesado en restricciones, realmente solo quiero saber los tipos de datos.

Author: JMP, 2009-10-21

9 answers

select * from information_schema.columns

Podría ayudarte a empezar.

 48
Author: erikkallen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 15:46:27

También puede insertar los resultados (o los 10 mejores resultados) en una tabla temporal y obtener las columnas de la tabla temporal (siempre que los nombres de las columnas sean todos diferentes).

SELECT TOP 10 *
INTO #TempTable
FROM <DataSource>

Luego use:

EXEC tempdb.dbo.sp_help N'#TempTable';

O

SELECT * 
FROM tempdb.sys.columns 
WHERE [object_id] = OBJECT_ID(N'tempdb..#TempTable');

Extrapolado de La respuesta de Aarón aquí.

 23
Author: Trisped,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:17:41

También puede usar...

SQL_VARIANT_PROPERTY()

{en los casos en los que no tiene acceso directo a los metadatos (por ejemplo, una consulta de servidor vinculado tal vez?).

Http://msdn.microsoft.com/en-us/library/ms178550.aspx

En SQL Server 2005 y posteriores es mejor usar las vistas de catálogo (sys.columnas) en lugar de INFORMATION_SCHEMA. A menos que la portabilidad a otras plataformas sea importante. Solo tenga en cuenta que las vistas INFORMATION_SCHEMA no cambiarán y por lo tanto lo harán carecer progresivamente de información sobre nuevas características, etc. en sucesivas versiones de SQL Server.

 17
Author: Aaron Bertrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 17:15:03

Allí DEBE ser una manera más fácil de hacer esto... Baja y he aquí, la hay...!

"sp_describe_first_result_set" es tu amigo!

Ahora me doy cuenta de que la pregunta se hizo específicamente para SQL Server 2000, pero estaba buscando una solución similar para versiones posteriores y descubrí algo de soporte nativo en SQL para lograr esto.

En SQL Server 2012 en adelante cf. "sp_describe_first_result_set" - Enlace a BOL

Ya había implementado un solución utilizando una técnica similar a @Trisped anterior y la arrancó para implementar la implementación nativa de SQL Server.

En caso de que aún no esté en SQL Server 2012 o Azure SQL Database, aquí está el proc almacenado que creé para las bases de datos de era anteriores a 2012:

CREATE PROCEDURE [fn].[GetQueryResultMetadata] 
    @queryText VARCHAR(MAX)
AS
BEGIN

    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    --SET NOCOUNT ON;

    PRINT @queryText;

    DECLARE
                @sqlToExec NVARCHAR(MAX) = 
                    'SELECT TOP 1 * INTO #QueryMetadata FROM ('
                    +
                    @queryText
                    +
                    ') T;'
                    + '
                        SELECT
                                    C.Name                          [ColumnName],
                                    TP.Name                         [ColumnType],
                                    C.max_length                    [MaxLength],
                                    C.[precision]                   [Precision],
                                    C.[scale]                       [Scale],
                                    C.[is_nullable]                 IsNullable
                        FROM
                                    tempdb.sys.columns              C
                                        INNER JOIN
                                    tempdb.sys.types                TP
                                                                                ON
                                                                                        TP.system_type_id = C.system_type_id
                                                                                            AND
                                                                                        -- exclude custom types
                                                                                        TP.system_type_id = TP.user_type_id
                        WHERE
                                    [object_id] = OBJECT_ID(N''tempdb..#QueryMetadata'');
            '

    EXEC sp_executesql @sqlToExec

END
 10
Author: Paul M Sorauer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-10 20:43:36

¿Puede recrear la tabla provisional desde cero cada vez que se ejecuta la consulta? Si es así usted podría utilizar SELECT ... INTO y deje que SQL Server se preocupe por crear la tabla utilizando los tipos de columna correctos, etc.

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc
 6
Author: LukeH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-10-21 15:51:32
SELECT COLUMN_NAME,
       DATA_TYPE,
       CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'

Puede usar alias de columnas para obtener una salida más atractiva.

 6
Author: PawelCz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 11:40:07

Para SQL Server 2012 y superiores: Si coloca la consulta en una cadena, puede obtener el conjunto de resultados tipos de datos como:

DECLARE @query nvarchar(max) = 'select 12.1 / 10.1 AS [Column1]';
EXEC sp_describe_first_result_set @query, null, 0;  
 4
Author: redcalx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-22 12:19:10
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME='yourTable';
 1
Author: bop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-17 11:39:33

Esto le dará todo lo relacionado con la propiedad de columna.

SELECT * INTO TMP1
FROM ( SELECT TOP 1 /* rest of your query expression here */ );

SELECT o.name AS obj_name, TYPE_NAME(c.user_type_id) AS type_name, c.*  
FROM sys.objects AS o   
JOIN sys.columns AS c  ON o.object_id = c.object_id  
WHERE o.name = 'TMP1';

DROP TABLE TMP1;
 1
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-16 15:58:08