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


70

我有一个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

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

Answers:


61
select * from information_schema.columns

可以帮助您入门。


4
您是否有CASE SENSITIVE数据库?如果是这样,您必须使用SELECT * FROM INFORMATION_SCHEMA.Columns
Raj More

1
是的,区分大小写。我尝试了SELECT * FROM INFORMATION_SCHEMA.Columns并得到了相同的无效对象错误。这是SQL Server 2000(8.0.2055),此版本中是否存在INFORMATION_SCHEMA?
JMP

5
好的nvm,我尝试了SELECT * FROM [databasename] .INFORMATION_SCHEMA.COLUNMS,现在到了。感谢您对此耐心等待!
JMP

1
如果您实际上是在尝试选择查询中返回的数据类型,这将无济于事-这只会评估静态表定义。 喂到任意查询时,请参阅下面的@redcalx答案,以获得实际的解决方案。
bsplosion

43

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

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

1
好答案!在哪里可以学习到其他有用的sp_过程?
Serhii Kushchenko

1
这是确定AdHoc脚本列的数据类型的黄金!之前,我使用Select-Into,然后研究创建的新表架构。这快得多!
MikeTeeVee

32

您还可以将结果(或前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');

亚伦的答案推断出来。


30

您也可以使用...

SQL_VARIANT_PROPERTY()

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

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


这不适用于文本字段。将会抛出此异常:“操作数类型冲突:文本与sql_variant不兼容”
eflles

3
@eflles谢谢,请记住这是一个特殊的情况下(当你没有访问元数据),甚至在2009年时这个问题上来,你应该已经放弃了textntextimage。如果人们今天仍在使用这些功能,那只是他们问题的一小部分...
Aaron Bertrand

21

必须是连接更简单的方法来做到这一点...低看哪,有...!

sp_describe_first_result_set ”是您的朋友!

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

在SQL Server 2012及更高版本中,请参见。“ sp_describe_first_result_set”-链接到BOL

我已经使用类似于@Trisped的技术实现了解决方案,并将其剥离以实现本机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

一个非常优雅的解决方案。
Paras Parmar,

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

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


6

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

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc

他还可以使用erikkallen指向的information_schema表来创建该登台表,以获取列数据类型。
Spidey

6
@JM:如何一次性运行SELECT ... INTO ... FROM ... WHERE 1=0语法以创建虚拟表,然后使用Management Studio编写虚拟表的表创建SQL脚本?
2009年

当数据源是表值函数时,这非常有用,在这种情况下您不能使用information_schema.columns。谢谢
lastr2d2 2014年

5

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

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;

这是迄今为止对原始问题的最简洁的答案。
roblem


2

我使用简单的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

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

0

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

选择CAST(0 AS BIT)AS OK


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');

这样,您可以找到列的数据类型。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.