2009-01-13 92 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等效自動的一些聰明的映射,但事實並非如此糟糕,保持片段短。

將這些類型的手動足夠的屁股痛的是擴展腳本是值得的。不確定我的轉換是否正確。