Mengurai Format File Teks Non-Standar dengan Komponen Skrip

Berlaku untuk: SQL Server SSIS Integration Runtime di Azure Data Factory

Ketika data sumber Anda diatur dalam format non-standar, Anda mungkin merasa lebih nyaman untuk mengonsolidasikan semua logika penguraian Anda dalam satu skrip daripada menyatukan beberapa transformasi Layanan Integrasi untuk mencapai hasil yang sama.

Contoh 1: Mengurai Rekaman Yang Dibatasi Baris

Contoh 2: Memisahkan Rekaman Induk dan Anak

Catatan

Jika Anda ingin membuat komponen yang dapat digunakan kembali dengan lebih mudah di beberapa tugas Aliran Data dan beberapa paket, pertimbangkan untuk menggunakan kode dalam sampel komponen Skrip ini sebagai titik awal untuk komponen aliran data kustom. Untuk informasi selengkapnya, lihat Mengembangkan Komponen Aliran Data Kustom.

Contoh 1: Mengurai Rekaman Yang Dibatasi Baris

Contoh ini memperlihatkan cara mengambil file teks di mana setiap kolom data muncul pada baris terpisah dan mengurainya ke dalam tabel tujuan dengan menggunakan komponen Skrip.

Untuk informasi selengkapnya tentang cara mengonfigurasi komponen Skrip untuk digunakan sebagai transformasi dalam aliran data, lihat Membuat Transformasi Sinkron dengan Komponen Skrip dan Membuat Transformasi Asinkron dengan Komponen Skrip.

Untuk mengonfigurasi contoh Komponen Skrip ini

  1. Buat dan simpan file teks bernama rowdelimiteddata.txt yang berisi data sumber berikut:

    FirstName: Nancy  
    LastName: Davolio  
    Title: Sales Representative  
    City: Seattle  
    StateProvince: WA  
    
    FirstName: Andrew  
    LastName: Fuller  
    Title: Vice President, Sales  
    City: Tacoma  
    StateProvince: WA  
    
    FirstName: Steven  
    LastName: Buchanan  
    Title: Sales Manager  
    City: London  
    StateProvince:  
    
    
  2. Buka Management Studio dan sambungkan ke instans SQL Server.

  3. Pilih database tujuan, dan buka jendela kueri baru. Di jendela kueri, jalankan skrip berikut untuk membuat tabel tujuan:

    create table RowDelimitedData  
    (  
    FirstName varchar(32),  
    LastName varchar(32),  
    Title varchar(32),  
    City varchar(32),  
    StateProvince varchar(32)  
    )  
    
    
  4. Buka SQL Server Data Tools dan buat paket Integration Services baru bernama ParseRowDelim.dtsx.

  5. Tambahkan manajer koneksi File Datar ke paket, beri nama RowDelimitedData, dan konfigurasikan untuk menyambungkan ke file rowdelimiteddata.txt yang Anda buat di langkah sebelumnya.

  6. Tambahkan manajer koneksi OLE DB ke paket dan konfigurasikan untuk menyambungkan ke instans SQL Server dan database tempat Anda membuat tabel tujuan.

  7. Tambahkan tugas Aliran Data ke paket dan klik tab Aliran Data dari SSIS Designer.

  8. Tambahkan Sumber File Datar ke aliran data dan konfigurasikan untuk menggunakan pengelola koneksi RowDelimitedData. Pada halaman Kolom Editor Sumber File Datar, pilih kolom eksternal tunggal yang tersedia.

  9. Tambahkan Komponen Skrip ke aliran data dan konfigurasikan sebagai transformasi. Sambungkan output Sumber File Datar ke Komponen Skrip.

  10. Klik dua kali komponen Skrip untuk menampilkan Editor Transformasi Skrip.

  11. Pada halaman Kolom Input dari Editor Transformasi Skrip, pilih kolom input tunggal yang tersedia.

  12. Pada halaman Input dan Output editor Transformasi Skrip, pilih Output 0 dan atur SynchronousInputID ke None. Buat 5 kolom output, semua string jenis [DT_STR] dengan panjang 32:

    • FirstName

    • LastName

    • Judul

    • Kota

    • StateProvince

  13. Pada halaman Skrip Editor Transformasi Skrip, klik Edit Skrip dan masukkan kode yang diperlihatkan di kelas ScriptMain contoh. Tutup lingkungan pengembangan skrip dan Editor Transformasi Skrip.

  14. Tambahkan Tujuan SQL Server ke aliran data. Konfigurasikan untuk menggunakan manajer koneksi OLE DB dan tabel RowDelimitedData. Sambungkan output Komponen Skrip ke tujuan ini.

  15. Jalankan paket. Setelah paket selesai, periksa rekaman dalam tabel tujuan SQL Server.

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)  
  
    Dim columnName As String  
    Dim columnValue As String  
  
    ' Check for an empty row.  
    If Row.Column0.Trim.Length > 0 Then  
        columnName = Row.Column0.Substring(0, Row.Column0.IndexOf(":"))  
        ' Check for an empty value after the colon.  
        If Row.Column0.Substring(Row.Column0.IndexOf(":")).TrimEnd.Length > 1 Then  
            ' Extract the column value from after the colon and space.  
            columnValue = Row.Column0.Substring(Row.Column0.IndexOf(":") + 2)  
            Select Case columnName  
                Case "FirstName"  
                    ' The FirstName value indicates a new record.  
                    Me.Output0Buffer.AddRow()  
                    Me.Output0Buffer.FirstName = columnValue  
                Case "LastName"  
                    Me.Output0Buffer.LastName = columnValue  
                Case "Title"  
                    Me.Output0Buffer.Title = columnValue  
                Case "City"  
                    Me.Output0Buffer.City = columnValue  
                Case "StateProvince"  
                    Me.Output0Buffer.StateProvince = columnValue  
            End Select  
        End If  
    End If  
  
End Sub  
public override void Input0_ProcessInputRow(Input0Buffer Row)  
    {  
  
        string columnName;  
        string columnValue;  
  
        // Check for an empty row.  
        if (Row.Column0.Trim().Length > 0)  
        {  
            columnName = Row.Column0.Substring(0, Row.Column0.IndexOf(":"));  
            // Check for an empty value after the colon.  
            if (Row.Column0.Substring(Row.Column0.IndexOf(":")).TrimEnd().Length > 1)  
            // Extract the column value from after the colon and space.  
            {  
                columnValue = Row.Column0.Substring(Row.Column0.IndexOf(":") + 2);  
                switch (columnName)  
                {  
                    case "FirstName":  
                        // The FirstName value indicates a new record.  
                        this.Output0Buffer.AddRow();  
                        this.Output0Buffer.FirstName = columnValue;  
                        break;  
                    case "LastName":  
                        this.Output0Buffer.LastName = columnValue;  
                        break;  
                    case "Title":  
                        this.Output0Buffer.Title = columnValue;  
                        break;  
                    case "City":  
                        this.Output0Buffer.City = columnValue;  
                        break;  
                    case "StateProvince":  
                        this.Output0Buffer.StateProvince = columnValue;  
                        break;  
                }  
            }  
        }  
  
    }  

Contoh 2: Memisahkan Rekaman Induk dan Anak

Contoh ini memperlihatkan cara mengambil file teks, di mana baris pemisah mendahului baris rekaman induk yang diikuti oleh jumlah baris rekaman anak yang tidak terbatas, dan mengurainya ke tabel tujuan induk dan anak yang dinormalisasi dengan benar dengan menggunakan komponen Skrip. Contoh sederhana ini dapat dengan mudah diadaptasi untuk file sumber yang menggunakan lebih dari satu baris atau kolom untuk setiap rekaman induk dan anak, selama ada beberapa cara untuk mengidentifikasi awal dan akhir setiap rekaman.

Perhatian

Sampel ini hanya ditujukan untuk tujuan demonstrasi. Jika Anda menjalankan sampel lebih dari sekali, sampel akan menyisipkan nilai kunci duplikat ke dalam tabel tujuan.

Untuk informasi selengkapnya tentang cara mengonfigurasi komponen Skrip untuk digunakan sebagai transformasi dalam aliran data, lihat Membuat Transformasi Sinkron dengan Komponen Skrip dan Membuat Transformasi Asinkron dengan Komponen Skrip.

Untuk mengonfigurasi contoh Komponen Skrip ini

  1. Buat dan simpan file teks bernama parentchilddata.txt yang berisi data sumber berikut:

    **********  
    PARENT 1 DATA  
    child 1 data  
    child 2 data  
    child 3 data  
    child 4 data  
    **********  
    PARENT 2 DATA  
    child 5 data  
    child 6 data  
    child 7 data  
    child 8 data  
    **********  
    
    
  2. Buka SQL Server Management Studio dan sambungkan ke instans SQL Server.

  3. Pilih database tujuan, dan buka jendela kueri baru. Di jendela kueri, jalankan skrip berikut untuk membuat tabel tujuan:

    CREATE TABLE [dbo].[Parents]([ParentID] [int] NOT NULL,  
    [ParentRecord] [varchar](32) NOT NULL,  
     CONSTRAINT [PK_Parents] PRIMARY KEY CLUSTERED   
    ([ParentID] ASC))  
    GO  
    CREATE TABLE [dbo].[Children]([ChildID] [int] NOT NULL,  
    [ParentID] [int] NOT NULL,  
    [ChildRecord] [varchar](32) NOT NULL,  
     CONSTRAINT [PK_Children] PRIMARY KEY CLUSTERED   
    ([ChildID] ASC))  
    GO  
    ALTER TABLE [dbo].[Children] ADD CONSTRAINT [FK_Children_Parents] FOREIGN KEY([ParentID])  
    REFERENCES [dbo].[Parents] ([ParentID])  
    
    
  4. Buka SQL Server Data Tools (SSDT) dan buat paket Integration Services baru bernama SplitParentChild.dtsx.

  5. Tambahkan manajer koneksi File Datar ke paket, beri nama ParentChildData, dan konfigurasikan untuk menyambungkan ke file parentchilddata.txt yang Anda buat di langkah sebelumnya.

  6. Tambahkan manajer koneksi OLE DB ke paket dan konfigurasikan untuk menyambungkan ke instans SQL Server dan database tempat Anda membuat tabel tujuan.

  7. Tambahkan tugas Aliran Data ke paket dan klik tab Aliran Data dari SSIS Designer.

  8. Tambahkan Sumber File Datar ke aliran data dan konfigurasikan untuk menggunakan pengelola koneksi ParentChildData. Pada halaman Kolom Editor Sumber File Datar, pilih kolom eksternal tunggal yang tersedia.

  9. Tambahkan Komponen Skrip ke aliran data dan konfigurasikan sebagai transformasi. Sambungkan output Sumber File Datar ke Komponen Skrip.

  10. Klik dua kali komponen Skrip untuk menampilkan Editor Transformasi Skrip.

  11. Pada halaman Kolom Input dari Editor Transformasi Skrip, pilih kolom input tunggal yang tersedia.

  12. Pada halaman Input dan Output editor Transformasi Skrip, pilih Output 0, ganti namanya menjadi ParentRecords, dan atur SynchronousInputID-nya menjadi None. Buat 2 kolom output:

    • ParentID (kunci utama), dari bilangan bulat bertanda tangan empat byte [DT_I4]

    • ParentRecord, dari jenis string [DT_STR] dengan panjang 32.

  13. Buat output kedua dan beri nama ChildRecords. SynchronousInputID dari output baru sudah diatur ke Tidak Ada. Buat 3 kolom output:

    • ChildID (kunci utama), dari bilangan bulat bertanda tangan empat byte [DT_I4]

    • ParentID (kunci asing), juga dari bilangan bulat bertanda tangan empat byte [DT_I4]

    • ChildRecord, dari jenis string [DT_STR] dengan panjang 50

  14. Pada halaman Skrip Editor Transformasi Skrip, klik Edit Skrip. Di kelas ScriptMain, masukkan kode yang ditampilkan dalam contoh. Tutup lingkungan pengembangan skrip dan Editor Transformasi Skrip.

  15. Tambahkan Tujuan SQL Server ke aliran data. Sambungkan output ParentRecords dari Komponen Skrip ke tujuan ini. Konfigurasikan untuk menggunakan pengelola koneksi OLE DB dan tabel Orang Tua.

  16. Tambahkan Tujuan SQL Server lain ke aliran data. Sambungkan output ChildRecords dari Komponen Skrip ke tujuan ini. Konfigurasikan untuk menggunakan pengelola koneksi OLE DB dan tabel Anak.

  17. Jalankan paket. Setelah paket selesai, periksa rekaman induk dan anak di dua tabel tujuan SQL Server.

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)  
  
    Static nextRowIsParent As Boolean = False  
    Static parentCounter As Integer = 0  
    Static childCounter As Integer = 0  
  
    ' If current row starts with separator characters,  
    '  then following row contains new parent record.  
    If Row.Column0.StartsWith("***") Then  
        nextRowIsParent = True  
    Else  
        If nextRowIsParent Then  
            ' Current row contains parent record.  
            parentCounter += 1  
            Me.ParentRecordsBuffer.AddRow()  
            Me.ParentRecordsBuffer.ParentID = parentCounter  
            Me.ParentRecordsBuffer.ParentRecord = Row.Column0  
            nextRowIsParent = False  
        Else  
            ' Current row contains child record.  
            childCounter += 1  
            Me.ChildRecordsBuffer.AddRow()  
            Me.ChildRecordsBuffer.ChildID = childCounter  
            Me.ChildRecordsBuffer.ParentID = parentCounter  
            Me.ChildRecordsBuffer.ChildRecord = Row.Column0  
        End If  
    End If  
  
End Sub  
public override void Input0_ProcessInputRow(Input0Buffer Row)  
    {  
  
    int static_Input0_ProcessInputRow_childCounter = 0;  
    int static_Input0_ProcessInputRow_parentCounter = 0;  
    bool static_Input0_ProcessInputRow_nextRowIsParent = false;  
  
        // If current row starts with separator characters,   
        // then following row contains new parent record.   
        if (Row.Column0.StartsWith("***"))  
        {  
            static_Input0_ProcessInputRow_nextRowIsParent = true;  
        }  
        else  
        {  
            if (static_Input0_ProcessInputRow_nextRowIsParent)  
            {  
                // Current row contains parent record.   
                static_Input0_ProcessInputRow_parentCounter += 1;  
                this.ParentRecordsBuffer.AddRow();  
                this.ParentRecordsBuffer.ParentID = static_Input0_ProcessInputRow_parentCounter;  
                this.ParentRecordsBuffer.ParentRecord = Row.Column0;  
                static_Input0_ProcessInputRow_nextRowIsParent = false;  
            }  
            else  
            {  
                // Current row contains child record.   
                static_Input0_ProcessInputRow_childCounter += 1;  
                this.ChildRecordsBuffer.AddRow();  
                this.ChildRecordsBuffer.ChildID = static_Input0_ProcessInputRow_childCounter;  
                this.ChildRecordsBuffer.ParentID = static_Input0_ProcessInputRow_parentCounter;  
                this.ChildRecordsBuffer.ChildRecord = Row.Column0;  
            }  
        }  
  
    }  

Lihat Juga

Membuat Transformasi Sinkron dengan Komponen Skrip
Membuat Transformasi Asinkron dengan Komponen Skrip