2009-01-13 94 views
8

我们有一个SQL查询,可以从数据库中抽取很多表/视图中的大量字段。我们需要将一个规范放在一起以便与第三方进行整合,编译结果集的数据类型的最快方法是什么?如何确定SQL结果的数据类型?

澄清:

  • 这里涉及25+表/视图,所以在表级的功能将仍然很麻烦。
  • 所有工作目前都在Microsoft SQL Server Management Studio中完成。
+0

这在很大程度上取决于什么语言/平台是用来检索这些值。 – 2009-01-13 18:20:37

回答

5

您可以运行与SET FMTONLY ON查询,但可能不会帮助您轻松确定数据类型返回,因为你只在管理工作室工作。 如果是我,我想我会暂时创建一个与存储过程相同的视图的视图(您可能需要为任何参数声明变量)。然后您可以查看已经讨论过的INFORMATION_SCHEMA查询所返回的列。

+1

创建视图使用NFORMATION_SCHEMA查询是缺少的一步,我需要! – Shawn 2009-01-13 19:06:40

2

如果您使用的是SQL Server,则可以在information_schema表中找到来自各种表的元数据。例如,为了获得列元数据表foo,发出该查询:

SELECT * FROM information_schema.columns WHERE table_name = 'Foo' 
1

如果您正在使用C#,你可以直接从外地访问的DataRow对象:

Type columnNameType = row["columnName"].GetType(); 
2

而对于一个附加的可选方案,你可以使用

sp_help 'Table_Name' 

编辑:此外,sp_help将可用于任何对象(即它会指示返回类型,的存储过程的输入和输出变量)

0

注意,结果集元数据是从表元数据不同,因为SQL查询可以包括表达式,其数据类型可以不相同,他们查询的表格中。

许多SQL查询接口给你一些函数来检索有关结果集元数据(数据类型等)的信息。

你需要使用特定的API函数取决于你所使用的语言和查询界面。你没有说明这一点。

举例来说,如果你正在使用ODBC,该SQLDescribeCol()功能可以给你有关结果集元数据信息。

8

通过使用临时表,您可以使用少量快速SQL语句查看结果列类型。

临时表是比较好一点的视图,因为它们是连接本地范围,将被清除一次断开。

所有你需要的是注入一些关键字如下

SELECT 
TOP 0 -- to speed up without access data 
your,original,columns 
INTO #T -- temp table magic 
FROM originalTablesJoins 
Order by anything 
exec tempdb.sys.sp_columns #T 
drop table #T 

;或

SELECT TOP 0 * FROM (
    select your,original,columns from originalTablesJoins -- remove order by if any 
) x 
exec tempdb.sys.sp_columns #T 
drop table #T 

注:由 View schema of resultset in SQL Server Management Studio

+0

对于第二个选项,我不得不这样做: SELECT TOP 0 * INTO #T FROM(... – 2015-11-03 22:25:53

1

启发这里有一个,如果你只是可以SELECT ... INTO #Temp(记住#Temp的作用范围是会话在最坏的情况),还有一些来自https://stackoverflow.com/a/14328779/162273被盗:

SELECT 
    c.name AS UsefulRawName, 
    ',' + c.name + ' ' + UPPER(t.name) + 
     CASE 
      WHEN t.name IN ('char', 'nchar', 'varchar', 'nvarchar') THEN '(' + CAST(c.max_length AS VARCHAR(3)) + ')' 
      WHEN t.name IN ('decimal', 'numeric') THEN '(' + CAST(c.[precision] AS VARCHAR(3)) + ', ' + CAST(c.[scale] AS VARCHAR(3)) + ')' 
      ELSE '' END + CASE WHEN c.Is_Nullable = 1 THEN ' NULL' ELSE ' NOT NULL' END AS SQLColumnType, 
    'public ' + 
     CASE 
      WHEN t.name IN ('varchar', 'nvarchar', 'text', 'ntext', 'char', 'nchar', 'xml', 'sysname') THEN 'string' 
      WHEN t.name IN ('binary', 'varbinary', 'image') THEN 'byte[]' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('uniqueidentifier') THEN 'Guid' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('datetimeoffset') THEN 'DateTimeOffset' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('date', 'time', 'datetime2', 'smalldatetime', 'datetime') THEN 'DateTime' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('numeric', 'decimal', 'real', 'money', 'smallmoney') THEN 'decimal' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('float') THEN 'float' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('tinyint', 'smallint') THEN 'short' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('int') THEN 'int' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('bit') THEN 'bool' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('bigint') THEN 'long' + CASE WHEN c.Is_Nullable = 1 THEN '?' ELSE '' END 
      WHEN t.name IN ('timestamp') THEN 'ulong' 
      ELSE 'object' END + ' ' + c.name + ' { get; set; }' AS CSColumnType, 
    c.name + ' = ' + 
     CASE 
      WHEN t.name IN ('varchar', 'nvarchar', 'text', 'ntext', 'char', 'nchar', 'xml', 'sysname') THEN 'reader["' + c.name + '"] as string,' 
      WHEN t.name IN ('binary', 'varbinary', 'image') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as byte[]?,' 
                 ELSE '(byte[])reader["' + c.name + '"],' END 
      WHEN t.name IN ('uniqueidentifier') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as Guid?,' 
                 ELSE '(Guid)reader["' + c.name + '"],' END 
      WHEN t.name IN ('datetimeoffset') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as DateTimeOffset?,' 
                 ELSE '(DateTimeOffset)reader["' + c.name + '"],' END 
      WHEN t.name IN ('date', 'time', 'datetime2', 'smalldatetime', 'datetime') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as DateTime?,' 
                 ELSE '(DateTime)reader["' + c.name + '"],' END 
      WHEN t.name IN ('numeric', 'decimal', 'real', 'money', 'smallmoney') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as decimal?,' 
                 ELSE '(decimal)reader["' + c.name + '"],' END 
      WHEN t.name IN ('float') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as float?,' 
                 ELSE '(float)reader["' + c.name + '"],' END 
      WHEN t.name IN ('tinyint', 'smallint') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as short?,' 
                 ELSE '(short)reader["' + c.name + '"],' END 
      WHEN t.name IN ('int') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as int?,' 
                 ELSE '(int)reader["' + c.name + '"],' END 
      WHEN t.name IN ('bit') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as bool?,' 
                 ELSE '(bool)reader["' + c.name + '"],' END 
      WHEN t.name IN ('bigint') THEN CASE 
                 WHEN c.Is_Nullable = 1 THEN 'reader["' + c.name + '"] as long?,' 
                 ELSE '(long)reader["' + c.name + '"],' END 
      WHEN t.name IN ('timestamp') THEN '(ulong)reader["' + c.name + '"],' 
      ELSE 'reader["' + c.name + '"] == DBNull.Value ? null : reader["' + c.name + '"],' END AS ReaderStatements 
FROM tempDb.sys.columns c 
INNER JOIN sys.types AS t ON c.system_type_id = t.system_type_id AND t.system_type_id = t.user_type_id 
WHERE [object_id] = OBJECT_ID('tempdb..#Temp') 
ORDER BY column_id 

更积极的人可以做的类型.NET等效自动的一些聪明的映射,但事实并非如此糟糕,保持片段短。

将这些类型的手动足够的屁股痛的是扩展脚本是值得的。不确定我的转换是否正确。