FIRSTROWパラメーターを使用したSQL一括挿入は次の行をスキップします
-
06-07-2019 - |
質問
これがどのように起こっているのか理解できないようです。
これは、SQL Server 2005に一括挿入しようとしているファイルの例です。
***A NICE HEADER HERE***
0000001234|SSNV|00013893-03JUN09
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
ここに私の一括挿入ステートメントがあります:
BULK INSERT sometable
FROM 'E:\filefromabove.txt
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
しかし、何らかの理由で私が得ることができる唯一の出力は次のとおりです。
0000005678|ABCD|00013893-03JUN09
0000009112|0000|00013893-03JUN09
0000009112|0000|00013893-03JUN09
ヘッダーを完全に削除し、FIRSTROWパラメーターを使用しない限り、最初のレコードは常にスキップされます。これはどのように可能ですか?
事前に感謝します!
解決
BULK INSERT
/ BCP
を使用して、異なる形式の行をスキップできるとは思わない。
これを実行すると:
TRUNCATE TABLE so1029384
BULK INSERT so1029384
FROM 'C:\Data\test\so1029384.txt'
WITH
(
--FIRSTROW = 2,
FIELDTERMINATOR= '|',
ROWTERMINATOR = '\n'
)
SELECT * FROM so1029384
なる:
col1 col2 col3
-------------------------------------------------- -------------------------------------------------- --------------------------------------------------
***A NICE HEADER HERE***
0000001234 SSNV 00013893-03JUN09
0000005678 ABCD 00013893-03JUN09
0000009112 0000 00013893-03JUN09
0000009112 0000 00013893-03JUN09
「|」が必要なようですヘッダーデータであっても、それまでは最初の列に読み込まれます。つまり、改行を最初の列に飲み込みます。明らかに、フィールドターミネータパラメータを含める場合、すべての行に MUST が必要であることが期待されます。
前処理ステップで行を削除できます。もう1つの可能性は、完全な行のみを選択して処理することです(ヘッダーを除外します)。または、SSISなど、これを処理できるツールを使用します。
他のヒント
( ROWTERMINATOR
で指定されているように)ヘッダーに実際のデータ行と同じ行末があることを確認しますか?
更新: MSDN から:
FIRSTROW属性は意図されていません 列ヘッダーをスキップします。スキップしています BULKはヘッダーをサポートしていません INSERTステートメント。行をスキップするとき、 SQL Serverデータベースエンジンの外観 フィールドターミネーターでのみ のデータを検証しません スキップされた行のフィールド。
行全体を1つの列に読み取ってから、XMLを使用してデータを解析するのが最も簡単であることがわかりました。
IF (OBJECT_ID('tempdb..#data') IS NOT NULL) DROP TABLE #data
CREATE TABLE #data (data VARCHAR(MAX))
BULK INSERT #data FROM 'E:\filefromabove.txt' WITH (FIRSTROW = 2, ROWTERMINATOR = '\n')
IF (OBJECT_ID('tempdb..#dataXml') IS NOT NULL) DROP TABLE #dataXml
CREATE TABLE #dataXml (ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY CLUSTERED, data XML)
INSERT #dataXml (data)
SELECT CAST('<r><d>' + REPLACE(data, '|', '</d><d>') + '</d></r>' AS XML)
FROM #data
SELECT d.data.value('(/r//d)[1]', 'varchar(max)') AS col1,
d.data.value('(/r//d)[2]', 'varchar(max)') AS col2,
d.data.value('(/r//d)[3]', 'varchar(max)') AS col3
FROM #dataXml d
以下のスニペットを使用できます
BULK INSERT TextData
FROM 'E:\filefromabove.txt'
WITH
(
FIRSTROW = 2,
FIELDTERMINATOR = '|', --CSV field delimiter
ROWTERMINATOR = '\n', --Use to shift the control to next row
ERRORFILE = 'E:\ErrorRows.csv',
TABLOCK
)
非SQLデータソースからSQL ServerにBCPをインポートした後、一部のデータがどのように破損するかを考えると、最初にいくつかのスクラッチテーブルにすべてのBCPインポートを行うことをお勧めします。
例
テーブルAddress_Import_tblの切り捨て
一括挿入dbo.Address_Import_tbl FROM 'E:\ external \ SomeDataSource \ Address.csv' WITH( FIELDTERMINATOR = '|'、ROWTERMINATOR = '\ n'、MAXERRORS = 10 )
アドレス_インポート_tblのすべての列がnvarchar()であることを確認し、できるだけ不可知論的にし、型変換エラーを回避します。
次に、必要な修正をAddress_Import_tblに適用します。不要なヘッダーを削除するなど。
次に、INSERT SELECTクエリを実行して、必要なデータ型変換とともにAddress_Import_tblからAddress_tblにコピーします。たとえば、インポートされた日付をSQL DATETIMEにキャストします。