web-dev-qa-db-fra.com

Comment renvoyer les types de données SQL de ma requête?

J'ai une requête SQL qui interroge une énorme base de données (comme des centaines de vues/tables avec des noms difficiles à lire comme CMM-CPP-FAP-ADD) que je n'ai ni besoin ni envie de comprendre. Le résultat de cette requête doit être stocké dans une table intermédiaire pour alimenter un rapport.

Je dois créer la table intermédiaire, mais avec des centaines de vues/tables dans lesquelles creuser pour trouver les types de données représentés, je me demande s'il existe un meilleur moyen de construire cette table.

Quelqu'un peut-il me dire comment utiliser l'un des outils SQL Server 2008 pour deviner les types de données source dans ma base de données SQL 2000?

Comme exemple général, je veux savoir à partir d'une requête comme:

SELECT Auth_First_Name, Auth_Last_Name, Auth_Favorite_Number 
FROM Authors

Au lieu des résultats réels, je veux savoir que:

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

Les contraintes ne m'intéressent pas, je veux simplement connaître les types de données.

51
JMP
select * from information_schema.columns

pourrait vous aider à démarrer.

53
erikkallen

Vous pouvez également insérer les résultats (ou les 10 meilleurs résultats) dans une table temporaire et extraire les colonnes de la table temporaire (tant que les noms des colonnes sont tous différents).

SELECT TOP 10 *
INTO #TempTable
FROM <DataSource>

Alors utilisez: 

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

ou

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

Extrapolée à partir de la réponse d'Aaron ici .

24
Trisped

Vous pouvez aussi utiliser...

SQL_VARIANT_PROPERTY()

... dans les cas où vous n'avez pas un accès direct aux métadonnées (par exemple, une requête de serveur lié peut-être?).

http://msdn.Microsoft.com/en-us/library/ms178550.aspx

Dans SQL Server 2005 et au-delà, il vaut mieux utiliser les vues de catalogue (sys.columns), par opposition à INFORMATION_SCHEMA. À moins que la portabilité vers d'autres plates-formes soit importante. N'oubliez pas que les vues INFORMATION_SCHEMA ne changeront pas et qu'elles manqueront progressivement d'informations sur les nouvelles fonctionnalités, etc., dans les versions successives de SQL Server.

19
Aaron Bertrand

Il y a DOIT un moyen plus facile de le faire ... Bas et voici, il y a ...!

"sp_describe_first_result_set} _" est votre ami!

Maintenant, je réalise que la question a été posée spécifiquement pour SQL Server 2000, mais je recherchais une solution similaire pour les versions ultérieures et découvris un support natif en SQL pour y parvenir.

Dans SQL Server 2012 et après cf. "sp_describe_first_result_set" - Lien vers BOL

J'avais déjà implémenté une solution utilisant une technique similaire à celle de @ Trisped above et je l'ai extraite pour implémenter l'implémentation native de SQL Server.

Si vous n'êtes pas encore sur SQL Server 2012 ou la base de données Azure SQL, voici le proc stocké que j'ai créé pour les bases de données antérieures à 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
11
Paul M Sorauer
SELECT COLUMN_NAME,
       DATA_TYPE,
       CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'

Vous pouvez utiliser des alias de colonnes pour une meilleure apparence.

7
Pawel Czapski

Pour SQL Server 2012 et les versions ultérieures: Si vous placez la requête dans une chaîne, vous pouvez obtenir les types de données d'ensemble de résultats comme suit:

DECLARE @query nvarchar(max) = 'select 12.1 / 10.1 AS [Column1]';
EXEC sp_describe_first_result_set @query, null, 0;  
6
redcalx

Pouvez-vous vous permettre de recréer la table intermédiaire à partir de zéro chaque fois que la requête est exécutée? Si tel est le cas, vous pouvez utiliser SELECT ... INTO syntax et laisser SQL Server s’inquiéter de la création de la table avec les types de colonne appropriés, etc.

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc
6
LukeH
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME='yourTable';
1
bop

Cela vous donnera tout ce qui concerne la propriété de la colonne.

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
user2074102

J'utilise une simple déclaration de cas pour rendre les résultats que je peux utiliser dans les documents de spécifications techniques. Cet exemple ne contient pas toutes les conditions que vous rencontrerez avec une base de données, mais il vous fournit un bon modèle à utiliser.

SELECT
     TABLE_NAME          AS 'Table Name',
     COLUMN_NAME         AS 'Column Name',
     CASE WHEN DATA_TYPE LIKE '%char'
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, CHARACTER_MAXIMUM_LENGTH) + ')'
          WHEN DATA_TYPE IN ('bit', 'int', 'smallint', 'date')
          THEN DATA_TYPE
          WHEN DATA_TYPE = 'datetime'
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, DATETIME_PRECISION) + ')'
          WHEN DATA_TYPE = 'float'
          THEN DATA_TYPE
          WHEN DATA_TYPE IN ('numeric', 'money')
          THEN DATA_TYPE + '(' + CONVERT(VARCHAR, NUMERIC_PRECISION) + ', ' + CONVERT(VARCHAR, NUMERIC_PRECISION_RADIX) + ')'
     END                 AS 'Data Type',
     CASE WHEN IS_NULLABLE = 'NO'
          THEN 'NOT NULL'
          ELSE 'NULL'
     END                 AS 'PK/LK/NOT NULL'
FROM INFORMATION_SCHEMA.COLUMNS 
ORDER BY 
     TABLE_NAME, ORDINAL_POSITION
1
rsidebot

sp_describe_first_result_set

aidera à identifier les types de données de requête en analysant les types de données du premier ensemble de résultats de requête

https://docs.Microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-describe-first-result-set-transact-sql?view=sql-server-2017

0
Alias Varghese