我们有一个SQL查询,可以从数据库中抽取很多表/视图中的大量字段。我们需要将一个规范放在一起以便与第三方进行整合,编译结果集的数据类型的最快方法是什么?如何确定SQL结果的数据类型?
澄清:
- 这里涉及25+表/视图,所以在表级的功能将仍然很麻烦。
- 所有工作目前都在Microsoft SQL Server Management Studio中完成。
我们有一个SQL查询,可以从数据库中抽取很多表/视图中的大量字段。我们需要将一个规范放在一起以便与第三方进行整合,编译结果集的数据类型的最快方法是什么?如何确定SQL结果的数据类型?
澄清:
您可以运行与SET FMTONLY ON查询,但可能不会帮助您轻松确定数据类型返回,因为你只在管理工作室工作。 如果是我,我想我会暂时创建一个与存储过程相同的视图的视图(您可能需要为任何参数声明变量)。然后您可以查看已经讨论过的INFORMATION_SCHEMA查询所返回的列。
创建视图使用NFORMATION_SCHEMA查询是缺少的一步,我需要! – Shawn 2009-01-13 19:06:40
如果您使用的是SQL Server,则可以在information_schema
表中找到来自各种表的元数据。例如,为了获得列元数据表foo,发出该查询:
SELECT * FROM information_schema.columns WHERE table_name = 'Foo'
如果您正在使用C#,你可以直接从外地访问的DataRow对象:
Type columnNameType = row["columnName"].GetType();
而对于一个附加的可选方案,你可以使用
sp_help 'Table_Name'
编辑:此外,sp_help将可用于任何对象(即它会指示返回类型,的存储过程的输入和输出变量)
注意,结果集元数据是从表元数据不同,因为SQL查询可以包括表达式,其数据类型可以不相同,他们查询的表格中。
许多SQL查询接口给你一些函数来检索有关结果集元数据(数据类型等)的信息。
你需要使用特定的API函数取决于你所使用的语言和查询界面。你没有说明这一点。
举例来说,如果你正在使用ODBC,该SQLDescribeCol()
功能可以给你有关结果集元数据信息。
通过使用临时表,您可以使用少量快速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
对于第二个选项,我不得不这样做: SELECT TOP 0 * INTO #T FROM(... – 2015-11-03 22:25:53
启发这里有一个,如果你只是可以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等效自动的一些聪明的映射,但事实并非如此糟糕,保持片段短。
将这些类型的手动足够的屁股痛的是扩展脚本是值得的。不确定我的转换是否正确。
这在很大程度上取决于什么语言/平台是用来检索这些值。 – 2009-01-13 18:20:37