2016-09-14 15 views
2

インポートエクスポートウィザードを使用してcsvファイルをテーブルにロードすると、デフォルトの数値列であるvarcharがインポート後にテーブルをスキャンできるため、テーブルをスキャンしてデータ型を見つけることができます。理想的なデータ型ですか?それはスキャンとデータ型の検索

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 

が含まれていA.csv例えば

は、csvファイルを考える私は、この使用してインポート・エクスポート・ウィザードをロードするときに、すべての列がvarchar型ですが、私はテーブルをスキャンし、データタイプを見つける必要があります。私は最初に正しいデータ型でデータを読み込むことに心配していません。私はテーブルにデータをロードした後、データ型を見つけるためにテーブルをスキャンした後しか気にしません。

+2

SSMSのデータインポートウィザード(提案するタイプボタン)がありますが、いくつかの制限があり、いつか奇妙な前提を作るので注意してください。 – ajeh

+0

これはアフターロードとどのくらい正確に機能しますか?あなたがタイプを知ったら何をするつもりです - 別のテーブルを作る? – Hogan

+0

はい正しいデータ型の新しいテーブルを作成する – Zack

答えて

2

6つの主要なデータ型を扱うようです。

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

expliciせずにこれを行うので、一つの方法あなたは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 

我々はすべてのデータ型をチェックしていないので、これは完璧ではないが、それはあなたが、少なくとも始める必要があります。 の機能を追加して、DECIMALの長さと精度、およびVARCHAR()の長さを設定する機能を把握することができます。しかし、値が不明なため、後続の挿入がバイナリデータを切り捨てるかどうかを知る方法はありません。だから、これらのフィールドの長さを入力時のフォローを受け入れるだけの大きさに設定する必要があります。また、これは、その列のすべての可能なデータ型を提供します。 12と12.34の場合はINTDECIMALが返され、DECIMALを選択する必要があります。これは、必要に応じて、後続の問合せで処理することができます。

+0

これは私の多くの最後の質問をどのようにブール値の列を決定するのに役立ちますあなたのために返事ありがとうございますか? – Zack

+0

@Zack 'BIT'は' 0,1、またはNULL'でもかまいません。これをcase文の最初の行に追加しました。 – scsimon

-2

あなたは列がに正常に変換することができるか発見するためにdatalength()convert()機能の組み合わせを使用し、正常に変換さの割合を見て、適切なデータ型を見つけることができますサポートしたいどのように多くの異なるデータ型に応じて、レコード対合計。

しかし、前にコメントしたように、ロード前にタイプを検出して時間とストレージリソースを無駄にすることを避けることをお勧めします。

+0

私は、それが一回であれば(質問ではっきりしない)、SELECTキャスト(整数型の列)をテーブルから実行して、エラーを報告します。 – 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? (それはYYYYDDMMまたはDDMMYYYYですか?)

どう12abについて:

  1. VARCHAR(1から8000)
  2. VARBINARY(1から8000)

どうtrueについて:

  1. VARCHAR(1から8000)
  2. BIT

そして、それは変換されません値のため1を返すようISNUMERICに依存することは信頼できないです。たとえば、一部の文化では、小数点を示すピリオドの代わりにコンマが使用されているため、有効な通貨量は次のとおりですが、その場合は予想通りに変換されません。

あるいは、受け入れ答えのコードを使用すると、以下が有効な「整数」と見なされる場合:

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_ sense ETLingデータを作成します。 –

関連する問題