Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

SSIS Задача за непоследователно импортиране на броя на колоните?

На върха на главата ми, имам 50% решение за вас.

Проблемът

SSIS наистина се грижи за метаданните, така че вариациите в тях обикновено водят до изключения. DTS беше много по-прощаващ в този смисъл. Тази силна нужда от последователни метаданни прави използването на плоския файлов източник проблемно.

Решение, базирано на заявка

Ако проблемът е в компонента, нека не го използваме. Това, което харесвам в този подход, е, че концептуално е същото като заявка за таблица – редът на колоните няма значение, нито наличието на допълнителни колони.

Променливи

Създадох 3 променливи, всички от тип низ:CurrentFileName, InputFolder и Query.

  • InputFolder е твърдо свързан към изходната папка. В моя пример това е C:\ssisdata\Kipreal
  • CurrentFileName е името на файл. По време на проектирането беше input5columns.csv но това ще се промени по време на изпълнение.
  • Заявката е израз "SELECT col1, col2, col3, col4, col5 FROM " + @[User::CurrentFilename]

Мениджър на връзки

Настройте връзка с входния файл с помощта на драйвера JET OLEDB. След като го създадох, както е описано в свързаната статия, го преименувах на FileOLEDB и зададох израз в ConnectionManager на "Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"

Контролен поток

Моят контролен поток изглежда като задача за поток от данни, вложена в преброител на файлове Foreach

Преброител за всеки файл

Моят преброител на файлове Foreach е конфигуриран да работи с файлове. Поставих израз в директорията за @[User::InputFolder] Забележете, че в този момент, ако стойността на тази папка трябва да се промени, тя ще бъде правилно актуализирана както в диспечера на връзките, така и в преброителя на файлове. В „Извличане на име на файл“ вместо „Напълно квалифициран“ по подразбиране изберете „Име и разширение“

В раздела Съпоставяне на променливи задайте стойността на нашия @[User::CurrentFileName] променлива

В този момент всяка итерация на цикъла ще промени стойността на @[User::Query за да отразява текущото име на файла.

Поток на данни

Това всъщност е най-лесното парче. Използвайте източник на OLE DB и го свържете, както е посочено.

Използвайте мениджъра на връзки FileOLEDB и променете режима за достъп до данни на „SQL команда от променлива“. Използвайте @[User::Query] променлива там, щракнете върху OK и сте готови за работа.

Примерни данни

Създадох два примерни файла input5columns.csv и input7columns.csv Всички колони от 5 са ​​в 7, но 7 ги има в различен ред (col2 е редна позиция 2 и 6). Отричах всички стойности в 7, за да стане ясно кой файл се оперира.

col1,col3,col2,col5,col4
1,3,2,5,4
1111,3333,2222,5555,4444
11,33,22,55,44
111,333,222,555,444

и

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

Изпълнението на пакета води до тези две екранни снимки

Какво липсва

Не знам начин да кажа на базирания на заявка подход, че е добре, ако колона не съществува. Ако има уникален ключ, предполагам, че бихте могли да дефинирате заявката си така, че да съдържа само колоните, които трябва бъдете там и след това извършете справки във файла, за да опитате да получите колоните, които трябва да бъде там и да не провали търсенето, ако колоната не съществува. Доста тъпо обаче.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Генериране на клас от таблицата на базата данни

  2. T-SQL съхранена процедура, която приема множество Id стойности

  3. Как мога да получа списъка с таблици в съхранената процедура?

  4. Как да предам списък като параметър в съхранена процедура?

  5. Комбинирайте две таблици, които нямат общи полета