Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Làm thế nào để nhập tệp văn bản có cùng tên và lược đồ nhưng khác thư mục vào cơ sở dữ liệu?

Đúng. Bạn sẽ muốn sử dụng Vùng chứa tệp Foreach và sau đó chọn tùy chọn Traverse Subfolder.

Chỉnh sửa

Rõ ràng câu trả lời của tôi không đủ sâu sắc, vì vậy vui lòng chấp nhận mã làm việc này minh họa những gì câu trả lời ban đầu ngắn gọn của tôi đã nêu.

Dữ liệu nguồn

Tôi đã tạo 3 thư mục như được mô tả ở trên để chứa các tệp sample1.txtsample2.txt

C:\>MKDIR SSISDATA\SO\TEST\201304
C:\>MKDIR SSISDATA\SO\TEST\201305
C:\>MKDIR SSISDATA\SO\TEST\201306

Nội dung của tập tin ở bên dưới. Mỗi phiên bản của tệp trong mỗi thư mục có giá trị ID tăng lên cùng với các giá trị văn bản được thay đổi để chứng minh nó đã chọn tệp mới.

ID,value
1,ABC

Tạo gói

Phần này giả sử bạn có Trình trợ giúp BIDS Cài đặt. Nó không bắt buộc đối với giải pháp mà chỉ cần cung cấp một khuôn khổ chung mà người đọc trong tương lai có thể sử dụng để tái tạo giải pháp này

Tôi đã tạo một tệp BIML với nội dung sau. Mặc dù tôi có bước tạo bảng trong đó, tôi cần phải chạy bước đó trên máy chủ đích trước khi tạo gói.

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <!-- Create a basic flat file source definition -->
    <FileFormats>
        <FlatFileFormat
            Name="FFFSrc"
            CodePage="1252"
            RowDelimiter="CRLF"
            IsUnicode="false"
            FlatFileType="Delimited"
            ColumnNamesInFirstDataRow="true"
        >
            <Columns>
                <Column
                    Name="ID"
                    DataType="Int32"
                    Delimiter=","
                    ColumnType="Delimited"
                />
                <Column
                    Name="value"
                    DataType="AnsiString"
                    Delimiter="CRLF"
                    InputLength="20"
                    MaximumWidth="20"
                    Length="20"
                    CodePage="1252"
                    ColumnType="Delimited"
                    />
            </Columns>
        </FlatFileFormat>
    </FileFormats>

    <!-- Create a connection that uses the flat file format defined above-->
    <Connections>
        <FlatFileConnection
            Name="FFSrc"
            FileFormat="FFFSrc"
            FilePath="C:\ssisdata\so\TEST\201306\sample1.txt"
            DelayValidation="true"
        />
        <OleDbConnection
            Name="tempdb"
            ConnectionString="Data Source=localhost\dev2012;Initial Catalog=tempdb;Provider=SQLNCLI11.1;Integrated Security=SSPI;Auto Translate=False;"
        />

    </Connections>

    <!-- Create a package to illustrate how to apply an expression on the Connection Manager -->
    <Packages>
        <Package
            Name="so_19957451"
            ConstraintMode="Linear"
        >
            <Connections>
                <Connection ConnectionName="tempdb"/>
                <Connection ConnectionName="FFSrc">
                    <Expressions>
                        <!-- Assign a variable to the ConnectionString property. 
                        The syntax for this is ConnectionManagerName.Property -->
                        <Expression PropertyName="FFSrc.ConnectionString">@[User::CurrentFileName]</Expression>
                    </Expressions>
                </Connection>
            </Connections>

            <!-- Create a single variable that points to the current file -->
            <Variables>
                <Variable Name="CurrentFileName" DataType="String">C:\ssisdata\so\TEST\201306\sample1.txt</Variable>
                <Variable Name="FileMask" DataType="String">*.txt</Variable>
                <Variable Name="SourceFolder" DataType="String">C:\ssisdata\so\TEST</Variable>
                <Variable Name="RowCountInput" DataType="Int32">0</Variable>
                <Variable Name="TargetTable" DataType="String">[dbo].[so_19957451]</Variable>
            </Variables>

            <!-- Add a foreach file enumerator. Use the above -->
            <Tasks>
                <ExecuteSQL 
                    Name="SQL Create Table"
                    ConnectionName="tempdb">
                    <DirectInput>
                        IF NOT EXISTS (SELECT * FROM sys.tables T WHERE T.name = 'so_19957451' and T.schema_id = schema_id('dbo'))
                        BEGIN
                            CREATE TABLE dbo.so_19957451(ID int NOT NULL, value varchar(20) NOT NULL);
                        END
                    </DirectInput>
                </ExecuteSQL>
                <ForEachFileLoop
                    Name="FELC Consume files"
                    FileSpecification="*.csv"
                    ProcessSubfolders="true"
                    RetrieveFileNameFormat="FullyQualified"
                    Folder="C:\"
                    ConstraintMode="Linear"
                >
                    <!-- Define the expressions to make the input folder and the file mask 
                    driven by variable values -->
                    <Expressions>
                        <Expression PropertyName="Directory">@[User::SourceFolder]</Expression>
                        <Expression PropertyName="FileSpec">@[User::FileMask]</Expression>
                    </Expressions>
                    <VariableMappings>
                        <!-- Notice that we use the convention of User.Variable name here -->
                        <VariableMapping
                            Name="0"
                            VariableName="User.CurrentFileName"
                        />
                    </VariableMappings>
                    <Tasks>
                        <Dataflow Name="DFT Import file" DelayValidation="true">
                            <Transformations>
                                <FlatFileSource Name="FFS Sample" ConnectionName="FFSrc"/>
                                <RowCount Name="RC Source" VariableName="User.RowCountInput"/>
                                <OleDbDestination 
                                    Name="OLE_DST"
                                    ConnectionName="tempdb">
                                    <TableFromVariableOutput VariableName="User.TargetTable"/>                                  
                                </OleDbDestination>
                            </Transformations>
                        </Dataflow>
                    </Tasks>
                </ForEachFileLoop>
            </Tasks>
        </Package>
    </Packages>
</Biml>

Nhấp chuột phải vào tệp biml và chọn Generate SSIS Package . Tại thời điểm này, bạn nên thêm gói có tên so_19957451 vào dự án SSIS hiện tại của mình.

Cấu hình gói

Không cần bất kỳ cấu hình nào vì nó đã được thực hiện thông qua BIML nhưng ảnh chụp màn hình moar giúp cho câu trả lời tốt hơn.

Đây là gói cơ bản

Đây là các biến của tôi

Cấu hình của Vòng lặp Foreach, như đã nêu trong bài viết MSDN cũng như ghi chú của tôi về việc chọn thư mục con Traverse

Gán giá trị được tạo trên mỗi vòng lặp cho biến Dòng điện

Nguồn tệp phẳng có một biểu thức được áp dụng cho thuộc tính ConnectionString để đảm bảo nó sử dụng Biến @User ::CurrentFileName. Điều này thay đổi nguồn mỗi lần thực thi vòng lặp.

Kết quả thực thi

Kết quả từ cơ sở dữ liệu

Khớp với đầu ra từ việc thực thi gói




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thay đổi loại dữ liệu của cột thành mã định danh duy nhất từ ​​bigint

  2. Truy xuất varbinary (MAX) từ SQL Server thành byte [] trong C #

  3. Sử dụng cột thứ tự sắp xếp trong bảng cơ sở dữ liệu

  4. Chuyển đổi DateTime thành yyyyMMddHHmm trong T-SQL

  5. Không thể tải SqlServerSpatial.dll