sql >> Databasteknik >  >> RDS >> Sqlserver

Hur kan jag ladda en stor platt fil i en databastabell med SSIS?

Förutsatt att du använder SQL Agent (eller liknande schemaläggare)

Reqs 1/4) Jag skulle låta ett föregångarsteg hantera FTP- och/eller filkopieringsstegen. Jag gillar inte att belamra mina paket med filmanipulation om jag kan undvika det.

Krav 2/3) På kontrollflödesnivån kommer paketdesignen att se ut som en Execute SQL-uppgift kopplad till ett Data Flow kopplat till en annan Execute SQL-uppgift. Som @AllenG indikerade skulle du vara bäst betjänad av att ladda in i en mellanställningstabell via uppgiften Dataflöde. Den första Execute SQL-uppgiften rensar alla rader från staging-tabellen (TRUNCATE TABLE dbo.DAILY_STAGE)

Ungefärlig bordsdesign ser ut så här. MICHAEL_BORN-tabellen är din befintliga tabell och DAILY_STAGE är där ditt dataflöde kommer att landa.

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
)

För demonstrationsändamål kommer jag att ladda ovanstående tabeller med exempeldata 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')

Uppgiften Execute SQL kommer att dra fördel av SAMMANSLUTNING uttalande tillgänglig i 2008+ utgåvor av SQL Server. Observera att det efterföljande semikolonet är en del av MERGE-satsen. Om det inte inkluderas kommer det att resultera i felet "En MERGE-sats måste avslutas med semikolon (;)."

-- 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
    ;

Krav 5) Effektivitet är helt baserat på dina data och hur breda dina rader är men det borde inte vara hemskt.

-- 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


  1. Vad är skillnaderna mellan SQL och MySQL

  2. MySQL InnoDB Cluster 8.0 - En komplett implementeringsgenomgång:del ett

  3. Vältalande grupp Genom att skapa SQLSTATE[42000] med giltig SQL-fråga i Laravel 5.3

  4. Hur man frågar jsonb-arrayer med IN-operator