Вывод значения переменной System.Object в плоский файл в службах SSIS.

Извините, если этот вопрос повторяется. У меня есть переменная system.object, в которой я храню результаты для запроса выбора. Мне нужно вывести результаты в плоский файл для дальнейшей обработки. У меня есть следующий фрагмент кода, который работает пару секунд, а затем выдает ошибку вызова системы. Не могли бы вы предложить какие-либо изменения в этом или если я делаю что-то не так:

 Public Sub Main()
    Dim x As New OleDb.OleDbDataAdapter
    Dim dt As New DataTable
    Dim str As String = vbNullString
    If System.IO.File.Exists("D:\BKP\AD.txt") = False Then
        System.IO.File.Create("D:\BKP\AD.txt")
    End If
    'MessageBox.Show("Hello")

    Dim i As Int32

    x.Fill(dt, Dts.Variables("User::LDAPResultSet").Value)
    i = dt.Rows.Count

    For j As Int32 = 0 To i - 1

        str = str & Join(dt.Rows.Item(j).ItemArray(), ",") & vbCrLf

    Next
    Dim objWriter As New System.IO.StreamWriter("D:\BKP\AD.txt")
    objWriter.Write(str)
    objWriter.Close()
End Sub
End Class

Есть ли лучший способ написать это или есть альтернативный фрагмент кода, который я бы тоже хотел попробовать. Спасибо за ваше время.


person rvphx    schedule 16.06.2016    source источник


Ответы (3)


Я делал это так в прошлом:

https://www.timmitchell.net/post/2015/04/20/using-the-ssis-object-variable-as-a-data-flow-source/

В основном передайте переменную в преобразование сценария, а затем добавьте данные в конвейер. С этого момента вы можете использовать целевой компонент как обычно и не создавать выходной файл и не ограничивать поля.

#region Namespaces
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion

// Add in the appropriate namespaces
using System.Data;
using System.Data.OleDb;

[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
    public override void CreateNewOutputRows()
    {
        // Set up the DataAdapter to extract the data, and the DataTable object to capture those results
        OleDbDataAdapter da = new OleDbDataAdapter();
        DataTable dt = new DataTable();

        // Extract the data from the object variable into the table
        da.Fill(dt, Variables.vResults);

        // Since we know the column metadata at design time, we simply need to iterate over each row in
        //  the DataTable, creating a new row in our Data Flow buffer for each
        foreach (DataRow dr in dt.Rows)
        {
            // Create a new, empty row in the output buffer
            SalesOutputBuffer.AddRow();

            // Now populate the columns
            SalesOutputBuffer.SalesOrderID = int.Parse(dr["SalesOrderID"].ToString());
            SalesOutputBuffer.RevisionNumber = int.Parse(dr["RevisionNumber"].ToString());
            SalesOutputBuffer.OrderDate = DateTime.Parse(dr["OrderDate"].ToString());
            SalesOutputBuffer.ShipDate = DateTime.Parse(dr["ShipDate"].ToString());
            SalesOutputBuffer.Status = int.Parse(dr["Status"].ToString());
            SalesOutputBuffer.TotalDue = decimal.Parse(dr["TotalDue"].ToString());
        } 
    }
}
person Joe C    schedule 16.06.2016
comment
Я пытаюсь следовать этому, но когда я запускаю скрипт, я получаю сообщение об ошибке, говорящее, что столбец «Имя столбца» не принадлежит таблице. Где я ошибаюсь? - person rvphx; 16.06.2016
comment
@rvphx проверьте назначение набора записей и посмотрите точное имя столбца. может быть дело в том, что вы что-то неправильно написали. - person marko982; 31.01.2020

Пункты из моего комментария:

  • Вам не нужно создавать файл: StreamWriter сделает это, если потребуется, в противном случае он перезапишет существующий файл.
  • String.Join(separator, values) - у вас есть разделитель в качестве второго аргумента.
  • Вы также должны вызвать objWriter.Dispose(), когда закончите его использовать.

Но:

  • Более эффективен для создания большой строки.
  • Вы можете написать весь текст за один раз, используя File.WriteAllText.
Sub Main()
    Dim outputFile As String = "D:\BKP\AD.txt"

    Dim x As New OleDb.OleDbDataAdapter
    Dim dt As New DataTable
    Dim sb As New Text.StringBuilder

    x.Fill(dt, Dts.Variables("User::LDAPResultSet").Value)

    For j As Integer = 0 To dt.Rows.Count - 1
        sb.AppendLine(String.Join(",", dt.Rows.Item(j).ItemArray()))
    Next

    IO.File.WriteAllText(outputFile, sb.ToString())

End Sub

Я предполагаю, что вы оставили несколько строк, связанных с OleDbDataAdapter, но я не знаком с SSIS.

Если можете, используйте Option Strict On — это указывало бы на проблема с String.Join для вас.

person Andrew Morton    schedule 16.06.2016

Это то, что сработало для меня, наконец:

    public override void CreateNewOutputRows()
{
    // Set up the DataAdapter to extract the data, and the DataTable object to capture those results
    OleDbDataAdapter da = new OleDbDataAdapter();
    DataTable dt = new DataTable();

    // Extract the data from the object variable into the table
    da.Fill(dt, Variables.LDAPResultSet);

    // Since we know the column metadata at design time, we simply need to iterate over each row in
    //  the DataTable, creating a new row in our Data Flow buffer for each
    foreach (DataRow dr in dt.Rows)
        //'foreach (DataColumn col in dt.Columns)
        {
            {
                // Create a new, empty row in the output buffer
                LDAPOutputBuffer.AddRow();
                object[] array = dr.ItemArray;
                LDAPOutputBuffer.ADENTName = array[1].ToString();
                LDAPOutputBuffer.DisplayName = array[3].ToString();
                LDAPOutputBuffer.DNName = array[2].ToString();
                LDAPOutputBuffer.Mail = array[0].ToString();
                               }
        }
}

}

person rvphx    schedule 16.06.2016