sql >> Database teknologi >  >> RDS >> Sqlserver

SSIS-opgave til import af inkonsistent kolonneantal?

Jeg har en 50 % løsning til dig.

Problemet

SSIS virkelig bekymrer sig om metadata, så variationer i dem har en tendens til at resultere i undtagelser. DTS var langt mere tilgivende i denne forstand. Det store behov for konsistente metadata gør brugen af ​​den flade filkilde besværlig.

Forespørgselsbaseret løsning

Hvis problemet er komponenten, lad os ikke bruge den. Det, jeg godt kan lide ved denne tilgang, er, at det konceptuelt er det samme som at forespørge i en tabel - rækkefølgen af ​​kolonner betyder ikke noget, og tilstedeværelsen af ​​ekstra kolonner betyder ikke noget.

Variabler

Jeg oprettede 3 variabler, alle af typen streng:CurrentFileName, InputFolder og Query.

  • InputFolder er fast forbundet til kildemappen. I mit eksempel er det C:\ssisdata\Kipreal
  • CurrentFileName er navnet på en fil. Under designtiden var det input5columns.csv men det vil ændre sig under kørslen.
  • Forespørgsel er et udtryk "SELECT col1, col2, col3, col4, col5 FROM " + @[Bruger::CurrentFilename]

Forbindelsesadministrator

Opsæt en forbindelse til inputfilen ved hjælp af JET OLEDB-driveren. Efter at have oprettet det som beskrevet i den linkede artikel, omdøbte jeg det til FileOLEDB og indstillede et udtryk på ConnectionManager for "Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB. 4.0;Udvidede egenskaber=\"tekst;HDR=Ja;FMT=CSVDebegrænset;\";"

Kontrol flow

Mit kontrolflow ligner en dataflowopgave indlejret i en Foreach-filtæller

Foreach File Enumerator

My Foreach File Enumerator er konfigureret til at fungere på filer. Jeg sætter et udtryk på mappen for @[Bruger::InputFolder] Bemærk, at på dette tidspunkt, hvis værdien af ​​denne mappe skal ændres, vil den blive opdateret korrekt i både forbindelseshåndteringen og filtælleren. I "Hent filnavn" skal du i stedet for standardindstillingen "Fuldt kvalificeret" vælge "Navn og udvidelse"

På fanen Variable Mappings skal du tildele værdien til vores @[User::CurrentFileName] variabel

På dette tidspunkt vil hver iteration af løkken ændre værdien af ​​@[User::Query for at afspejle det aktuelle filnavn.

Dataflow

Dette er faktisk det nemmeste stykke. Brug en OLE DB-kilde, og tilslut den som angivet.

Brug FileOLEDB-forbindelseshåndteringen og skift dataadgangstilstanden til "SQL-kommando fra variabel." Brug @[User::Query] variabel derinde, klik på OK, og du er klar til at arbejde.

Eksempel på data

Jeg oprettede to eksempelfiler input5columns.csv og input7columns.csv Alle kolonnerne af 5 er i 7, men 7 har dem i en anden rækkefølge (col2 er ordensposition 2 og 6). Jeg negerede alle værdierne i 7 for at gøre det klart, hvilken fil der bliver opereret på.

col1,col3,col2,col5,col41,3,2,5,41111,3333,2222,5555,444411,33,22,55,44111,333,222,555,444 

og

col1,col3,col7,col5,col4,col6,col2-1111,-3333,-7777,-5555,-4444,-6666,-2222-111,-333,-777,-555 ,-444,-666,-222-1,-3,-7,-5,-4,-6,-2-11,-33,-77,-55,-44,-666,-222

Kørsel af pakken resulterer i disse to skærmbilleder

Hvad mangler

Jeg kender ikke en måde at fortælle den forespørgselsbaserede tilgang, at det er OK, hvis en kolonne ikke eksisterer. Hvis der er en unik nøgle, formoder jeg, at du kan definere din forespørgsel til kun at have de kolonner, der skal være der og derefter udføre opslag mod filen for at prøve at få de kolonner, der burde at være der og ikke fejle opslaget, hvis kolonnen ikke eksisterer. Temmelig kludgey dog.



  1. Hvordan får man en liste over MySQL-visninger?

  2. ORA - 00933 forveksling med indre sammenføjning og som

  3. Opret forbindelse til ekstern MySQL-database via SSH ved hjælp af Java

  4. Sådan fjerner du en kolonne i SQL Server ved hjælp af T-SQL