如何从查询中返回SQL数据类型?

时间:2009-10-21 15:42:33

标签: sql sql-server tsql sql-server-2008

我有一个SQL查询,它查询一个我不需要也不想理解的巨大数据库(如数百个具有难以读取的名称的表,如CMM-CPP-FAP-ADD)数据库。此查询的结果需要存储在临时表中以提供报告。

我需要创建临时表,但是要查看数百个视图/表来查找此处表示的数据类型,我不得不怀疑是否有更好的方法来构建此表。

有人可以建议我如何使用任何SQL Server 2008工具来划分我的SQL 2000数据库中的源数据类型吗?

作为一般例子,我想通过以下查询来了解:

SELECT Auth_First_Name, Auth_Last_Name, Auth_Favorite_Number 
FROM Authors

而不是实际结果,我想知道:

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

我对约束不感兴趣,我真的只想知道数据类型。

13 个答案:

答案 0 :(得分:54)

select * from information_schema.columns

可以帮助你开始。

答案 1 :(得分:24)

您还可以将结果(或前10个结果)插入到临时表中,并从临时表中获取列(只要列名称都不同)。

SELECT TOP 10 *
INTO #TempTable
FROM <DataSource>

然后使用:

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

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

Aaron's answer here推断。

答案 2 :(得分:21)

你也可以使用......

SQL_VARIANT_PROPERTY()

...如果您无法直接访问元数据(例如,可能是链接服务器查询?)。

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

在SQL Server 2005及更高版本中,最好使用目录视图(sys.columns)而不是INFORMATION_SCHEMA。除非对其他平台的可移植性很重要。请记住,INFORMATION_SCHEMA视图不会更改,因此它们将逐步缺少SQL Server连续版本中的新功能等信息。

答案 3 :(得分:14)

必须更简单的方法来做到这一点......瞧不起,有......!

sp_describe_first_result_set ”是您的朋友!

现在我意识到这个问题是专门针对SQL Server 2000提出的,但我正在为更高版本寻找类似的解决方案,并在SQL中发现了一些原生支持来实现这一目标。

在SQL Server 2012中,参考cf. “sp_describe_first_result_set” - Link to BOL

我已经使用类似于上面@Trisped's的技术实现了一个解决方案,并将其解压缩以实现本机SQL Server实现。

如果您还没有使用SQL Server 2012或Azure SQL数据库,这里是我为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

答案 4 :(得分:12)

对于SQL Server 2012及更高版本:如果将查询放入字符串中,则可以获得结果集数据类型,如下所示:

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

答案 5 :(得分:7)

SELECT COLUMN_NAME,
       DATA_TYPE,
       CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'

您可以使用列别名来获得更好的输出效果。

答案 6 :(得分:6)

每次执行查询时,您是否可以从头开始重新创建临时表?如果是这样,您可以使用SELECT ... INTO语法,让SQL Server担心使用正确的列类型等创建表。

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc

答案 7 :(得分:1)

select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_NAME='yourTable';

答案 8 :(得分:1)

这将为您提供与列属性相关的所有内容。

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;

答案 9 :(得分:1)

  

sp_describe_first_result_set

通过分析查询的第一个结果集的数据类型将有助于识别查询的数据类型

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

答案 10 :(得分:1)

我使用一个简单的case语句来呈现可以在技术规范文档中使用的结果。此示例并未包含您将要在数据库中遇到的所有条件,但是它为您提供了一个很好的模板。

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

答案 11 :(得分:0)

此简单查询返回一个数据类型位。您可以将此主题用于其他数据类型:

选择CAST(0 AS BIT)AS

答案 12 :(得分:0)

检查数据类型。 检查SQL Server数据库数据类型的第一种方法是使用SYS模式表进行查询。以下查询使用COLUMNS和TYPES表:

    SELECT C.NAME AS COLUMN_NAME,
       TYPE_NAME(C.USER_TYPE_ID) AS DATA_TYPE,
       C.IS_NULLABLE,
       C.MAX_LENGTH,
       C.PRECISION,
       C.SCALE
FROM SYS.COLUMNS C
JOIN SYS.TYPES T
     ON C.USER_TYPE_ID=T.USER_TYPE_ID
WHERE C.OBJECT_ID=OBJECT_ID('your_table_name');

通过这种方式,您可以找到列的数据类型。