我們有一個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