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

JMP*_*JMP 58 sql t-sql sql-server 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
Run Code Online (Sandbox Code Playgroud)

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

Auth_First_Name is char(25)
Auth_Last_Name is char(50)
Auth_Favorite_Number is int
Run Code Online (Sandbox Code Playgroud)

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

eri*_*len 58

select * from information_schema.columns
Run Code Online (Sandbox Code Playgroud)

可以让你开始.

  • 好的nvm,我尝试了SELECT*FROM [databasename] .INFORMATION_SCHEMA.COLUNMS,我到了某个地方.感谢您对此我有耐心! (5认同)
  • 你有CASE SENSITIVE数据库吗?如果是这样,您必须使用`SELECT*FROM INFORMATION_SCHEMA.Columns` (3认同)
  • 如果您实际上尝试选择查询中返回的数据类型,这并没有帮助 - 这仅评估静态表定义。[请参阅下面@redcalx的答案](/sf/answers/3245364251/),了解提供任意查询时的实际解决方案。 (3认同)
  • 是的,区分大小写。我尝试 SELECT * FROM INFORMATION_SCHEMA.Columns 并得到相同的无效对象错误。这是SQL Server 2000 (8.0.2055),该版本中是否存在INFORMATION_SCHEMA? (2认同)

Tri*_*ped 26

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

SELECT TOP 10 *
INTO #TempTable
FROM <DataSource>
Run Code Online (Sandbox Code Playgroud)

然后使用:

EXEC tempdb.dbo.sp_help N'#TempTable';
Run Code Online (Sandbox Code Playgroud)

要么

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

Aaron的回答中推断出来.


Aar*_*and 24

你也可以用......

SQL_VARIANT_PROPERTY()
Run Code Online (Sandbox Code Playgroud)

...在您无法直接访问元数据的情况下(例如,链接的服务器查询可能?).

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

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

  • @eflles谢谢,记住这是一个例外情况(当你无法访问元数据时),即使在2009年出现这个问题时,你也应该放弃`text`,`ntext`和`image`.如果人们今天仍在使用这些,这只是他们问题的一小部分...... (3认同)

red*_*alx 23

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

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

  • 很好的答案!我在哪里可以学习另一个像这样有用的 sp_ 程序? (2认同)
  • 这是确定即席脚本列的数据类型的黄金!之前,我使用 Select-Into,然后研究创建的新表架构。这要快得多! (2认同)

Pau*_*uer 18

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

" sp_describe_first_result_set "是你的朋友!

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

在SQL Server 2012中,参考cf. "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
Run Code Online (Sandbox Code Playgroud)


Paw*_*ski 7

SELECT COLUMN_NAME,
       DATA_TYPE,
       CHARACTER_MAXIMUM_LENGTH
FROM information_schema.columns
WHERE TABLE_NAME = 'YOUR_TABLE_NAME'
Run Code Online (Sandbox Code Playgroud)

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


Luk*_*keH 6

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

SELECT *
INTO your_staging_table
FROM enormous_collection_of_views_tables_etc
Run Code Online (Sandbox Code Playgroud)

  • @JM:如何运行`SELECT ... INTO ... FROM ... WHERE 1 = 0`语法作为一次性创建一个虚表,然后使用Management Studio编写表创建SQL的脚本假表? (6认同)

小智 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;
Run Code Online (Sandbox Code Playgroud)