Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment puis-je charger un gros fichier plat dans une table de base de données à l'aide de SSIS ?

En supposant que vous utilisez SQL Agent (ou un planificateur similaire)

Reqs 1/4) J'aurais une étape précurseur pour gérer les étapes FTP et/ou de copie de fichiers. Je n'aime pas encombrer mes packages avec la manipulation de fichiers si je peux l'éviter.

Reqs 2/3) Au niveau du flux de contrôle, la conception du package va ressembler à une tâche d'exécution SQL connectée à un flux de données connecté à une autre tâche d'exécution SQL. Comme @AllenG l'a indiqué, vous feriez mieux de charger dans une table intermédiaire via la tâche de flux de données. La première tâche d'exécution SQL purgera toutes les lignes de la table intermédiaire (TRUNCATE TABLE dbo.DAILY_STAGE)

La conception approximative de la table ressemble à ceci. La table MICHAEL_BORN est votre table existante et DAILY_STAGE est l'endroit où votre flux de données atterrira.

CREATE TABLE DBO.MICHAEL_BORN
(
    ID int identity(1,1) NOT NULL PRIMARY KEY CLUSTERED
,   ItemID int NOT NULL
,   ItemName varchar(20) NOT NULL
,   ItemType varchar(20) NOT NULL
)
CREATE TABLE dbo.DAILY_STAGE
(
    ItemID int NOT NULL PRIMARY KEY CLUSTERED
,   ItemName varchar(20) NOT NULL
,   ItemType varchar(20) NOT NULL
)

À des fins de démonstration, je vais charger les tableaux ci-dessus avec des exemples de données via TSQL

-- Original data
INSERT INTO
    dbo.MICHAEL_BORN
VALUES
    (2345,'Apple','Fruit')
,   (4578, 'Bannana','Fruit')


-- Daily load runs
-- Adds a new fruit (pear), corrects misspelling of banana, eliminates apple
INSERT INTO
    dbo.DAILY_STAGE
VALUES
    (7721,'Pear','Fruit')
,   (4578, 'Banana','Fruit')

La tâche d'exécution SQL tirera parti de la MERGE déclaration disponible dans les éditions 2008+ de SQL Server. Veuillez noter que le point-virgule final fait partie de l'instruction MERGE. Si vous ne l'incluez pas, l'erreur "Une instruction MERGE doit se terminer par un point-virgule (;)" s'affichera.

-- MERGE statement
-- http://technet.microsoft.com/en-us/library/bb510625.aspx
-- Given the above scenario, this script will
-- 1)  Update the matched (4578 bannana/banana) row
-- 2)  Add the new (pear) row
-- 3)  Remove the unmatched (apple) row

MERGE
    dbo.[MICHAEL_BORN] AS T
USING
(
    SELECT
        ItemID
    ,   ItemName
    ,   ItemType
    FROM
        dbo.DAILY_STAGE

) AS S
ON T.ItemID = S.ItemID
WHEN
    MATCHED THEN
    UPDATE
    SET
        T.ItemName = S.ItemName
    ,   T.ItemType = S.ItemType
WHEN
    NOT MATCHED THEN
    INSERT
    (
        ItemID
    ,   ItemName
    ,   ItemType
    )
    VALUES
    (
        ItemID
    ,   ItemName
    ,   ItemType
    )
WHEN
    NOT MATCHED BY SOURCE THEN
    DELETE
    ;

Req 5) L'efficacité est totalement basée sur vos données et la largeur de vos lignes, mais cela ne devrait pas être terrible.

-- Performance testing
-- Assumes you have a similar fast row number generator function
-- http://billfellows.blogspot.com/2009/11/fast-number-generator.html

TRUNCATE TABLE dbo.MICHAEL_BORN
TRUNCATE TABLE dbo.DAILY_STAGE

-- load initial rows
-- 20ish seconds
INSERT INTO
    dbo.MICHAEL_BORN
SELECT
    N.number AS ItemID
,   'Spam & eggs ' + CAST(N.number AS varchar(10)) AS ItemName
,   'SPAM' AS ItemType
--, CASE N.number % 2 WHEN 0 THEN N.number + 1000000 ELSE N.number END AS UpTheEvens
FROM
    dbo.GenerateNumbers(1000000) N


-- Load staging table
-- Odds get item type switched out
-- Evens get delete and new ones created
-- 20ish seconds
INSERT INTO
    dbo.DAILY_STAGE
SELECT
    CASE N.number % 2 WHEN 0 THEN N.number + 1000000 ELSE N.number END AS ItemID
,   'Spam & eggs ' + CAST(N.number AS varchar(10)) AS ItemName
,   CASE N.number % 2 WHEN 0 THEN 'SPAM' ELSE 'Not much spam' END AS ItemType
FROM
    dbo.GenerateNumbers(1000000) N


-- Run MERGE statement, 32 seconds 1.5M rows upserted
-- Probably fast enough for you