0
4

2 に答える 2

0

(少なくとも) 2 つのオプションがあります。

  1. 好みのスクリプト言語を使用して、ファイルを SQL Server の外部で 2 つの個別のファイルに分割します。1 つはヘッダー行、もう 1 つは詳細行です。次に、2 つのBULK INSERTステートメントを使用して、それらを 2 つの異なるテーブルにロードします。
  2. SSIS とスクリプト タスクを使用して、ファイルを 2 つのデータ フローに分割し、パッケージ内でそれぞれを個別に処理します。

個人的にはオプション 1 を使用しますが、はるかに簡単です。また、データを一時テーブルにロードする理由はありません。このデータをロードするためだけに永続的なテーブル (またはテーブル) を作成します。これは、作業がはるかに簡単です。

于 2013-01-16T18:17:15.847 に答える
0

Pondlife へのアドバイスに感謝します。私は自分の質問に対する答えを得ました。どうぞ;

ご存知のように、ヘッダーと詳細を同時に含むこのテキスト ファイルがあります。

HR|001580/06|RG|2013/11/01 12:00|BG|3573|001580| IT|001580/01|1|00147066||1200|852.3|830.3|1.35|UNIDAD|0|31/12/2014 00:00 IT|001580/02|1|00147066||200|852.3|830.3|1.35| UNIDAD|1|2014/12/31 00:00 IT|001580/03|1|00147066||100|852.3|830.3|1.35|UNIDAD|55|2014/12/31 00:00 IT|001580/04|2 |00254276||200|852.3|830.3|1.35|UNIDAD|0|31/12/2014 00:00 IT|001580/05|3|00305359||1700|852.3|830.3|1.35|UNIDAD|0|31/12 /2014 00:00 IT|001580/06|3|00305359||300|852.3|830.3|1.35|UNIDAD|1|2014/12/31 00:00

だから私はする必要があります:

  1. ファイルを読む
  2. ヘッダーを table1 に挿入します
  3. 詳細を table2 に挿入します

最初のステップでは、テーブルを作成してから、Sql BulkInsert を使用します

CREATE TABLE #ImportData
(
    Field VARCHAR(max)
)
-- Insert the data into the first table
BULK INSERT #ImportData
FROM 'PATH FILE'
WITH 
( 
    ROWTERMINATOR = '\n'
)

私はこのようなものを手に入れました。


行に区切り記号 ( | ) があることがわかります。これは、各テーブルのフィールド (HR - ヘッダー、IT - 詳細) を意味します。

次に、2 番目と 3 番目のステップでは、各テーブルに行を挿入する必要がありますが、各行の各フィールドを分離する必要もあるため、文字列と区切り文字を受け取り、文字列の各フィールドを含むテーブルを返すプロシージャを作成します。フィールドを動的に作成しました。

プロシージャを作成する場合は、最初にこれを実行する必要があります SET QUOTED_IDENTIFIER OFF 。次に、作成できます。

--EXEC spSplit
--  @InputString = 'IT|001580/01|1|00147066||1200|852.3|830.3|1.35|QUANTITY|0|31/12/2014 00:00', -- VARCHAR(max)
--  @Delimiter = '|' -- VARCHAR(50)

--SET QUOTED_IDENTIFIER OFF
ALTER PROCEDURE spSplit
-- =============================================
-- Author:      Gabriel Jiménez
-- Create date: 2013-01-16
-- Description: Procedimiento creado para retornar
-- valores de cada campo de una cadena delimitada 
-- =============================================
    @InputString    NVARCHAR(max),
    @Delimiter      VARCHAR(50)

AS
BEGIN

    SET QUOTED_IDENTIFIER OFF

    CREATE TABLE #Items (Field1 VARCHAR(max))

    DECLARE @Item           VARCHAR(max)
    DECLARE @ItemList       VARCHAR(max)
    DECLARE @DelimIndex     INT
    DECLARE @PositionField  INT 
    DECLARE @SqlTable       VARCHAR(max)
    DECLARE @SqlUpdate      VARCHAR(max)

    SET @ItemList = @InputString
    SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)
    SET @PositionField = 0

    WHILE (@DelimIndex != 0) 
    BEGIN

        SET @SqlTable = "ALTER TABLE #Items ADD Field"
        SET @SqlUpdate = "UPDATE #Items SET Field"

        -- Set positions Rows and Fields 
        SET @PositionField = @PositionField + 1
        SET @Item = SUBSTRING(@ItemList, 0, @DelimIndex)

        IF @PositionField = 1
        BEGIN
            -- Insert the first data into the first field created on the table
            INSERT INTO #Items (Field1) VALUES ( @Item )
        END
        ELSE
        BEGIN
            -- Create a dynamic table for the @InputString
            SET @SqlTable = @SqlTable + CONVERT(VARCHAR, @PositionField)+ " VARCHAR(MAX)"
            EXEC(@SqlTable)

            SET @SqlUpdate = @SqlUpdate + 
                CONVERT(VARCHAR, @PositionField) + " = '" + 
                CONVERT(VARCHAR, @Item) +"'"
            EXEC(@SqlUpdate)

        END

        -- Set @ItemList = @ItemList minus one less item
        SET @ItemList = SUBSTRING(@ItemList, @DelimIndex+1, LEN(@ItemList)-@DelimIndex)
        SET @DelimIndex = CHARINDEX(@Delimiter, @ItemList, 0)

    END -- End WHILE

    IF @Item IS NOT NULL -- At least one delimiter was encountered in @InputString
    BEGIN
        SET @SqlTable = "ALTER TABLE #Items ADD Field"
        SET @SqlUpdate = "UPDATE #Items SET Field"
        SET @SqlTable = @SqlTable + CONVERT(VARCHAR, @PositionField+1)+ " VARCHAR(MAX)"
        EXEC(@SqlTable)

        SET @SqlUpdate = @SqlUpdate + 
            CONVERT(VARCHAR, @PositionField+1) + " = '" + 
            CONVERT(VARCHAR, @ItemList) +"'"
        EXEC(@SqlUpdate)

    END
    -- No delimiters were encountered in @InputString, so just return @InputString
    ELSE 
    BEGIN
        SET @SqlTable = "ALTER TABLE #Items ADD Field"
        SET @SqlUpdate = "UPDATE #Items SET Field"
        SET @SqlTable = @SqlTable + CONVERT(VARCHAR, @PositionField+1)+ " VARCHAR(MAX)"
        EXEC(@SqlTable)

        SET @SqlUpdate = @SqlUpdate + 
            CONVERT(VARCHAR, @PositionField+1) + " = '" + 
            CONVERT(VARCHAR, @InputString) +"'"
        EXEC(@SqlUpdate)

    END 

    SELECT * FROM #Items

    SET QUOTED_IDENTIFIER ON 
END -- End Procedure
GO

手順を実行するために最初の 3 行をコメントすると、次のような結果が得られます。

まだ終了していません。ファイルを読み取り、フィールドを返すプロシージャを作成します。次に、各テーブルに挿入する必要があります。そのために、静的フィールドを持つ 2 つの一時テーブルを作成します。各テーブルのフィールドを知っているからです。 #ImpoData テーブルの各行を読み取るための Cursor を作成します。

CREATE TABLE #Header
(
    Field1 VARCHAR(max),
    Field2 VARCHAR(max),
    Field3 VARCHAR(max),
    Field4 VARCHAR(max),
    Field5 VARCHAR(max),
    Field6 VARCHAR(max),
    Field7 VARCHAR(max),
    Field8 VARCHAR(max)
)
-- Detail table is for the detail items 
CREATE TABLE #Detail
(
    Field1 VARCHAR(max),
    Field2 VARCHAR(max),
    Field3 VARCHAR(max),
    Field4 VARCHAR(max),
    Field5 VARCHAR(max),
    Field6 VARCHAR(max),
    Field7 VARCHAR(max),
    Field8 VARCHAR(max),
    Field9 VARCHAR(max),
    Field10 VARCHAR(max),
    Field11 VARCHAR(max),
    Field12 VARCHAR(max)
)

DECLARE @Field NVARCHAR(max)
DECLARE Header CURSOR        
    FOR SELECT  Field
        FROM    #ImportData
        WHERE SUBSTRING(Field,1,2) = 'HR'
OPEN Header
FETCH NEXT FROM Header INTO @Field

WHILE @@FETCH_STATUS = 0           
    BEGIN 
        INSERT INTO #Header
        EXEC spSplit @Field, '|'
        FETCH NEXT FROM Header INTO @Field
    END                              
CLOSE Header
DEALLOCATE Header

--Detail
--DECLARE @f NVARCHAR(max)
DECLARE Detail CURSOR        
    FOR SELECT  Field
        FROM    #ImportData
        WHERE SUBSTRING(Field,1,2) = 'IT'
OPEN Detail
FETCH NEXT FROM Detail INTO @Field

WHILE @@FETCH_STATUS = 0           
    BEGIN 
        INSERT INTO #Detail
        EXEC spSplit @Field, '|'
        FETCH NEXT FROM Detail INTO @Field
    END                              
CLOSE Detail
DEALLOCATE Detail

--SELECT * FROM #ImportData
SELECT * FROM #Header
SELECT * FROM #Detail

DROP TABLE #ImportData
DROP TABLE #Header
DROP TABLE #Detail

その後、すべてのピースを同じクエリに配置すると、これが得られます。

必要に応じて。


分割のアドバイスをくれた Pondlife にもう一度感謝します。

于 2013-01-17T17:10:31.040 に答える