2016-09-14 72 views
2

我們可以掃描表並找到數據類型,因爲當我們使用導入導出嚮導它默認甚至是數字列VARCHAR加載csv文件到表中,我們可以導入後掃描表並找到數據類型可能是理想的?掃描和查找數據類型

例如,考慮一個CSV文件A.csv它包含

ColumnA ColumnB ColumnC ColumnD ColumnE 
1234  xyz  123.4 1  abc123 
4258  acv  785.6 0  abs58 
785  fgf  879.6 1  ftrd15 
448  wsd 87878.6 0  wewe 
78528  ews 6968.2 1  awaq 
525554 qwe  2.3 0  afgd87 

所以當我加載此使用導入導出嚮導的所有列是VARCHAR,但我需要掃描表,然後找到的數據類型。我不關心加載數據的正確數據類型,我最初只關心將數據加載到表中,然後掃描表以找到數據類型。

+2

SSMS數據導入嚮導可以建議的數據類型(建議 類型按鈕),但要小心,因爲它有一些限制,並在某個時候做出奇怪的假設。 – ajeh

+0

這與後負荷工作到底如何?一旦你知道這種類型 - 做另一張桌子會怎麼辦? – Hogan

+0

是使用正確的數據類型創建一個新表 – Zack

回答

2

看起來你會處理的6分主要的數據類型。

  1. DATETIME
  2. INTEGER
  3. DECIMAL
  4. CHARACTER
  5. VARCHAR
  6. BIT

所以一個這樣做沒有explici方式TLY想每一個轉換,趕上一個錯誤,因爲你不能在2008年使用TRY_CONVERT,是利用ISDATE, ISNUMERICCHARINDEX。對於每一列,你可以做這樣的事情。當然,你可以在每個列的遊標中執行此操作,或者僅複製case語句幾次,或者使用交叉連接。

SELECT DISTINCT 
'ColumnA' as ColumnName, 
CASE 
    WHEN ISNUMERIC(ColumnA) = 1 AND LEN(ColumnA) = 1 AND ColumnA NOT LIKE '%[2-9]%' THEN 'Bit', 
    WHEN ISNUMERIC(ColumnA) = 1 AND CHARINDEX('.',ColumnA) > 0 THEN 'Decimal' 
    WHEN ISNUMERIC(ColumnA) = 1 AND CHARINDEX('.',ColumnA) = 0 THEN 'Integer' 
    WHEN ISDATE(ColumnA) = 1 THEN 'Date' 
    WHEN LEN(ColumnA) = 1 AND ColumnA LIKE '%[a-z]%' THEN 'Character' 
    ELSE 'VARCHAR' 
END AS DataTypeCheck 
FROM YourTable 

這並不完美,因爲我們沒有檢查所有的數據類型,但至少應該讓你開始。你可以添加一些更LEN()功能找出你想要設置你的DECIMAL長度和精度,以及你VARCHAR()長什麼。但是,無法知道插入後續操作是否會導致二進制數據被截斷......因爲值是未知的。所以你只需要設置這些字段長度足夠大,以接受任何後續輸入。此外,這將爲您提供該列所有可能的數據類型。所以如果你有12和12.34,它將返回INTDECIMAL,其中你應該選擇DECIMAL。如果需要,這可以在後續查詢中處理。

+0

非常感謝你的回覆,這有助於我的事業很多最後一個問題如何確定一個布爾列? – Zack

+0

@Zack你使用'BIT'可以是'0,1或NULL'。我將此添加到案例陳述的第一行。 – scsimon

-2

根據你想要多少個不同的數據類型的支持,您可以使用convert()功能的組合與datalength()發現哪些列可以被成功地轉化,並找出正確的數據類型看的成功轉換率記錄與總數。

但我還是建議裝車到避免浪費時間和存儲資源,正如我在前面的評論之前發現的類型。

+0

我認爲如果它是一次(不是由問題清楚),您可以執行'SELECT cast(columna as integer)FROM table'並查看它是否會更容易報告錯誤。 – Hogan

+0

是的,如果它是一次性的,並且數據集很小......我們沒有完整的OP要求。然後有這整個蠕蟲被稱爲「髒數據」。 – ajeh

+2

低估年。 :D – Hogan

1

這個問題是非常有問題的。數據的目標/預期用途決定了數據類型,而不是數據的不完整掃描。 要確定數據類型是什麼,不容易出錯代碼(以及任何代碼容易出錯)。例如,如果數據類型是什麼20122010

  1. INT/BIGINT
  2. FLOAT
  3. VARCHAR(1 - 8000)
  4. VARBINARY(1 - 8000)
  5. DATE/DATETIME? (它是YYYYDDMMDDMMYYYY?)

什麼12ab

  1. VARCHAR(1 - 8000)
  2. VARBINARY(1 - 8000)

什麼true

  1. VARCHAR(1 - 8000)

而且依賴於ISNUMERIC是不可靠的,因爲它對於不會轉換值返回1。例如,在某些文化中,使用逗號代替十進制的句點,因此以下是有效的貨幣數量,但它不會按照人們預期的方式轉換:

SELECT ISNUMERIC('212012,00'); -- 1 
SELECT CONVERT(MONEY, '212012,95') AS [Money]; -- 21201295.00 

或者,如果使用公認的答案代碼,以下將被視爲一個有效的「整數」:

SELECT CONVERT(INT, '212012,00') AS [Int]; -- error 
-- Msg 245, Level 16, State 1, Line 3 
-- Conversion failed when converting the varchar value '212012,00' to data type int. 

這個怎麼樣:

SELECT ISNUMERIC('212,012.00,0,1'); -- 1 
+0

逗號的編碼很容易。不知道你爲什麼強調這麼多。大家都說OP不應該這樣去做。我甚至說它並不完美。感謝您的重複與例子。他們是很好的例子 – scsimon

+0

@scsimon源文件是一個CSV文件,所以也許「數字」不會嵌入逗號,這會消除一些複雜性。儘管如此,我還以爲還有其他「奇怪的」ISNUMERIC行爲,這使得它不可靠,超出了逗號。但我沒有強調這一點。我舉了幾個例子,其中類型_不能根據值來確定。任何解決方案的工作都有太多的含糊之處。我知道你說這是一個好的開始,並不完美。問題不在於你的解決方案,而在於要求。它使_no_感覺ETLing數據到系統中而不知道它是什麼。 –