2

クライアントから CSV を取得しています。そのファイルをデータベースにインポートする必要があります。私は数え切れないほどの繰り返しを経験してきましたが、解決策の一部は無限にテストされています。私の問題は、完全な解決策が必要なときに発生します。

CSV には 14 のフィールドがあり、tempdb データベースには 15 のフィールドがあります (最後の 1 つは ID 列です)。データは ID なしで到着し、データベースの設計に従って行の一意の番号が必要です。

表示されているテスト データを隠しましたが、データは正常に模倣されています。

T2012-DAT;09-01-2012;09-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5
T2012-DAT;10-01-2012;10-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5
T2012-DAT;11-01-2012;11-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5
T2012-DAT;12-01-2012;12-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5
T2012-DAT;13-01-2012;13-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7
T2012-DAT;16-01-2012;16-01-2012;1;910,91;12;TST;4,55;200,2;6;;;;7,5

tempdb に作成する一時テーブル。15 個のフィールドがあり、最後の 1 つは必要な ID です。

CREATE TABLE BudgetImport(
    sBudgetName varchar(20) COLLATE Danish_Norwegian_CI_AS  
    , dStartDate varchar(12) COLLATE Danish_Norwegian_CI_AS  
    , dEndDate varchar(12) COLLATE Danish_Norwegian_CI_AS   
    、prCode int   
    , decTotal varchar(20) COLLATE Danish_Norwegian_CI_AS
    , sRefTimeTypeID varchar(10) COLLATE Danish_Norwegian_CI_AS  
    , sRefEmployeeID varchar(10) COLLATE Danish_Norwegian_CI_AS  
    , decHours varchar(20) COLLATE Danish_Norwegian_CI_AS  
    , decRate varchar(20) COLLATE Danish_Norwegian_CI_AS
    , sDepartmentID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL  
    , sCentre varchar(10) COLLATE Danish_Norwegian_CI_AS NULL  
    , sPurpose varchar(10) COLLATE Danish_Norwegian_CI_AS NULL  
    , sProjectID varchar(10) COLLATE Danish_Norwegian_CI_AS NULL  
    , decNormHours varchar(20) COLLATE Danish_Norwegian_CI_AS  
    --, iRowNumber int ID(500000,1)  
)

行く

-- csvでデータをインポート
 BULK INSERT BudgetImport
 FROM 'D:\budgetposter.csv'
 と
 (
    フィールドターミネーター = ';'
    、rowterminator = '\r\n'
    、コードページ = '1252'
 )

ID を含めると、次のエラーが発生します。

メッセージ 4866、レベル 16、状態 1、行 3
一括読み込みに失敗しました。データ ファイルの行 1、列 15 の列が長すぎます。フィールド ターミネータと行ターミネータが正しく指定されていることを確認してください。

除外すると、エラーは次のように変わります。

メッセージ 4866、レベル 16、状態 1、行 3
一括読み込みに失敗しました。データ ファイルの行 1、列 14 の列が長すぎます。フィールド ターミネータと行ターミネータが正しく指定されていることを確認してください。

を変更するrowterminator = '\n' と が届きますが、ID がありません。

次にIDを含めると、エラーは次のようになります。

メッセージ 4864、レベル 16、状態 1、行 3
行 1、列 15 (iRowNumber) の一括読み込みデータ変換エラー (型の不一致または指定されたコードページの無効な文字)。

私がテストしているとき、私は を除外して、単独でINSERT INTO dbo."the-real-datatable"やっています。SELECT FROM BudgetImportしたがって、実データテーブルにさらに 16000 行を挿入することは避けています。

注意を払ってハンガリー語表記を知っていれば、datatime または decimal が正しい形式である場合でも、varchar を使用していることに気付くでしょう。私は約4〜6時間のテストと頭痛と引き裂かれた髪の無限の供給の後にこれを行っています. Varchar は KISS ソリューションですCONVERT()。後で行います。

私の問題全体は、行の最後のフィールドで解決します。- 1 と 2 を追加してみました。decNormHours の後に、空の値 (; ; または ;1; または ;n;) を追加しようとしました。- 私は formatfile.xml で試しました - 再びケーキはありません。formatfile を使用するよりも、使用しない方が成功しました。・イギリスの数字表記、 に変更してみました。= DK表記でより多くの成功。- 思いついたすべてのトリックを試しましたが、役に立ちませんでした。

はい、CSV に ID フィールドはありません。問題ありません。identity(500000,1)テーブルの作成で説明したデフォルトの auto を使用するだけです。ああ、500000は私が今到達したおおよその行IDです。時間の経過とともに増加します。

これを改善するには、次に何を試す必要がありますか?

編集:
フォーマットファイルの使用

$lt;? xml バージョン="1.0" ? $gt;
$lt;BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"$gt;
 $lt;RECORD$gt;
  FIELD ID="1" xsi:type="NCharTerm" TERMINATOR=";" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="2" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="3" xsi:type="CharFixed" LENGTH="9" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="4" xsi:type="NCharTerm" TERMINATOR=";"/
  FIELD ID="5" xsi:type="NCharTerm" TERMINATOR=";"/
  FIELD ID="6" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="7" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="8" xsi:type="NCharTerm" TERMINATOR=";"/
  FIELD ID="9" xsi:type="NCharTerm" TERMINATOR=";"/
  FIELD ID="10" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="11" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="12" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="50" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="13" xsi:type="NCharTerm" TERMINATOR=";" MAX_LENGTH="20" COLLATION="SQL_Latin1_General_CP1_CI_AS"/
  FIELD ID="14" xsi:type="NCharTerm" TERMINATOR=";"/
 /記録
 行
  COLUMN SOURCE="1" NAME="sBudgetName" xsi:type="SQLNVARCHAR" LENGTH="20" /
  COLUMN SOURCE="2" NAME="dStartDate" xsi:type="SQLDATETIME"/
  COLUMN SOURCE="3" NAME="dEndDate" xsi:type="SQLDATETIME"/
  COLUMN SOURCE="4" NAME="prCode" xsi:type="SQLSMALLINT"/
  COLUMN SOURCE="5" NAME="decTotal" xsi:type="SQLDECIMAL"/
  COLUMN SOURCE="6" NAME="sRefTimeTypeID" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="7" NAME="sRefEmployeeID" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="8" NAME="decHours" xsi:type="SQLDECIMAL"/
  COLUMN SOURCE="9" NAME="decRate" xsi:type="SQLDECIMAL"/
  COLUMN SOURCE="10" NAME="sDepartmentID" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="11" NAME="Centre" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="12" NAME="目的" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="13" NAME="sRefProjectID" xsi:type="SQLNVARCHAR" LENGTH="10"/
  COLUMN SOURCE="14" NAME="decNormHours" xsi:type="SQLDECIMAL"/
/行

最初のフィールドを正しく機能させることに戻ります。つまり、最終的な詳細を正しくするために戦うことから、そもそもそれを機能させるために戦うことになり、何かをすることになります。エラー:

メッセージ 4863、レベル 16、状態 1、行 3
行 1、列 1 (sBudgetName) の一括読み込みデータ変換エラー (切り捨て)。

注:うーん、SOはxmlが好きではないようです。奇妙です。

4

1 に答える 1

0

これは解決策よりも回避策ですが、列数の問題に直面しているので、後にインデックス列を追加してみませんか?

あなたはこのようなことをすることができます:

  • 同じ列数の一時テーブルにCSVをインポートします

それで、

ALTER TABLE BudgetImport
    ADD Id  INTEGER
GO

WITH Cte
AS
(
    SELECT *
    , ROW_NUMBER() OVER(ORDER BY [**column of your choice**] DESC) AS RowNumber
    FROM BudgetImport
)
UPDATE Cte
SET Id = RowNumber
GO

ALTER TABLE BudgetImport
ALTER COLUMN Id INTEGER NOT NULL 
GO

ALTER TABLE BudgetImport
ADD PRIMARY KEY (Id)
GO
于 2012-10-25T12:09:57.390 に答える