Tôi có một giải pháp 50% cho bạn.
Sự cố
SSIS thực sự quan tâm đến dữ liệu meta nên các biến thể trong đó có xu hướng dẫn đến ngoại lệ. DTS đã dễ dàng tha thứ hơn theo nghĩa này. Nhu cầu cao về dữ liệu meta nhất quán khiến việc sử dụng Nguồn tệp phẳng trở nên rắc rối.
Giải pháp dựa trên truy vấn
Nếu vấn đề là thành phần, chúng ta không sử dụng nó. Điều tôi thích ở cách tiếp cận này là về mặt khái niệm, nó giống như truy vấn một bảng - thứ tự của các cột không quan trọng và sự hiện diện của các cột bổ sung cũng không quan trọng.
Các biến
Tôi đã tạo 3 biến, tất cả đều thuộc loại chuỗi:CurrentFileName, InputFolder và Query.
- InputFolder được kết nối cố định với thư mục nguồn. Trong ví dụ của tôi, đó là
C:\ssisdata\Kipreal
- CurrentFileName là tên của một tệp. Trong thời gian thiết kế, nó là
input5columns.csv
nhưng điều đó sẽ thay đổi vào thời gian chạy. - Truy vấn là một biểu thức
"SELECT col1, col2, col3, col4, col5 FROM " + @[User::CurrentFilename]
Trình quản lý kết nối
Thiết lập kết nối với tệp đầu vào bằng trình điều khiển JET OLEDB. Sau khi tạo nó như được mô tả trong bài viết được liên kết, tôi đã đổi tên nó thành FileOLEDB và đặt biểu thức trên Trình quản lý kết nối của "Data Source=" + @[User::InputFolder] + ";Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=\"text;HDR=Yes;FMT=CSVDelimited;\";"
Luồng kiểm soát
Luồng kiểm soát của tôi trông giống như một tác vụ Luồng dữ liệu được lồng trong một trình liệt kê tệp Foreach
Foreach File Enumerator
Trình kê khai tệp Foreach của tôi được định cấu hình để hoạt động trên tệp. Tôi đặt một biểu thức trên Thư mục cho @[User::InputFolder]
Lưu ý rằng tại thời điểm này, nếu giá trị của thư mục đó cần thay đổi, thì nó sẽ được cập nhật chính xác trong cả Trình quản lý kết nối và trình kê khai tệp. Trong "Truy xuất tên tệp", thay vì "Đủ tiêu chuẩn" mặc định, hãy chọn "Tên và tiện ích mở rộng"
Trong tab Ánh xạ biến, chỉ định giá trị cho @[User::CurrentFileName]
của chúng tôi biến
Tại thời điểm này, mỗi lần lặp lại của vòng lặp sẽ thay đổi giá trị của @[User::Query
để phản ánh tên tệp hiện tại.
Luồng dữ liệu
Đây thực sự là phần dễ nhất. Sử dụng nguồn OLE DB và nối nguồn như được chỉ ra.
Sử dụng trình quản lý kết nối FileOLEDB và thay đổi chế độ Truy cập Dữ liệu thành "Lệnh SQL từ biến". Sử dụng @[User::Query]
trong đó, nhấp vào OK và bạn đã sẵn sàng làm việc.
Dữ liệu mẫu
Tôi đã tạo hai tệp mẫu input5columns.csv và input7columns.csv Tất cả các cột của 5 nằm trong 7 nhưng 7 có chúng theo một thứ tự khác (col2 là vị trí thứ tự 2 và 6). Tôi đã phủ định tất cả các giá trị trong 7 để dễ dàng biết được tệp nào đang được vận hành.
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
và
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
Việc chạy gói sẽ tạo ra hai ảnh chụp màn hình này
Điều gì còn thiếu
Tôi không biết có cách nào để nói với phương pháp dựa trên truy vấn rằng không sao cả nếu một cột không tồn tại. Nếu có một khóa duy nhất, tôi cho rằng bạn có thể xác định truy vấn của mình để chỉ có các cột phải ở đó và sau đó thực hiện tra cứu đối với tệp để thử và lấy các cột nên ở đó và không thất bại trong việc tra cứu nếu cột không tồn tại. Tuy nhiên, khá đẹp.