2012-04-01 310 views
0

SQL Server 2008を使用しており、5つのchar型の列を持つテーブルがあります。SQL Server BULK INSERT固定長charデータ

CREATE TABLE [dbo].[deviceDataBulk](
[f1] [char](9) NULL, 
[f2] [char](5) NULL, 
[f3] [char](7) NULL, 
[f4] [char](7) NULL, 
[f5] [char](6) NULL) 

また、bcp形式のファイルもあります。

<RECORD> 
<FIELD ID="1" xsi:type="CharFixed" LENGTH="9" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="2" xsi:type="CharFixed" LENGTH="5" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="3" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="4" xsi:type="CharFixed" LENGTH="7" COLLATION="Turkish_CI_AS"/> 
<FIELD ID="5" xsi:type="CharFixed" LENGTH="6" COLLATION="Turkish_CI_AS"/> 
</RECORD> 
<ROW> 
<COLUMN SOURCE="1" NAME="f1" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="2" NAME="f2" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="3" NAME="f3" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="4" NAME="f4" NULLABLE="YES" xsi:type="SQLCHAR"/> 
<COLUMN SOURCE="5" NAME="f5" NULLABLE="YES" xsi:type="SQLCHAR"/> 
</ROW> 

私のデータファイルには、各行にフィールドターミネータを持たない固定長のcharデータが含まれています。したがって、フルラインは34文字になります。

私の問題はフィールド4で、フィールド5は各行に存在しない可能性があります。私はそのファイルに21行の長い行または28行の長さの行を持つことができます。

フィールド5が存在し、フィールド4が存在しない場合はありません。

可能なシナリオはテキストファイルです。

f1 f2 f3 f4 f5 
f1 f2 f3 f4 
f1 f2 f3 

BULK INSERTでこのファイルを挿入できませんでした。私はBULK INSERTは、それらのフィールドを持っていないときにnullを挿入したい、ツールが行の終わりに達すると、残りのフィールドにnullを挿入するだけです。

答えて

0

2段階アプローチはどうですか?最初にデータをステージングテーブルに「大きな行」としてロードし、2番目のクエリを使用して生の行を対応するフィールドに分割し、それに応じて「見つからないf5および/またはf4列」を処理しますか?

は、このような(多かれ少なかれ)になります。(!未テスト)を

CREATE TABLE [dbo].[deviceDataBulk_staging](
[rowid] int IDENTITY(1 , 1) PRIMARY KEY, 
[raw] [varchar](34) NOT NULL) 

GO 
BULK INSERT [deviceDataBulk_staging] 
FROM '<your file>' 
-- not sure if you really need a format-file here, 
-- simply make sure to pass the correct line-separator if it is 'exotic'. 

GO 

INSERT [deviceDataBulk] (f1, f2, f3, f4, f5) 
SELECT f1 = SubString([raw], 1 , 9), 
     f1 = SubString([raw], 10 , 5), 
     f1 = SubString([raw], 15 , 7), 
     f1 = (CASE WHEN Length([raw] < 22 THEN NULL ELSE SubString([raw], 22 , 7) END), 
     f1 = (CASE WHEN Length([raw] < 29 THEN NULL ELSE SubString([raw], 29 , 6) END) 
    FROM [deviceDataBulk_staging] 
ORDER BY [rowid] 

ステージングファイルは、次にようになります。

[行ID]と同じ順序を維持することがありますあなたがそれを必要としないかもしれませんが、IMHOのオーバーヘッドは最小ですし、MSSQLはHEAPテーブルに熱心ではありませんので、 "良いこと[Tm]"

+0

これが唯一の解決策であればSQL Serverを使用してこれらのchar値を解析するか、 c#windowsアプリケーションとそれを解析する(ファイルから行ごとに読み込み、解析して行を挿入する)。私は状況を集計しようとしていた、実際には、ターゲットテーブルは35の列を持ち、最後の6は空であるかもしれません。データファイルには60行のデータがあります。 5分ごとに新しいデータファイルが作成されます。 –

+0

これは唯一の解決策であり、この方法を選択していただきありがとうございます。 –

+0

60行のデータが必要な場合は、パフォーマンスについてあまり心配しません。 SQLは文字列操作(言語は何ですか?)ではそれほど大きくないかもしれませんが、まともな仕事IMHOを行います。 35列の文を書くことは楽しいことではありませんが、= P – deroby

関連する問題