将 System.Object 变量值输出到 SSIS 中的平面文件

Output the System.Object variable value to a flat file in SSIS

如果这个问题是重复的,我很抱歉。我有一个 system.object 变量,用于存储 select 查询的结果。我需要将结果输出到平面文件以进一步处理它。我有以下代码可以运行几秒钟,然后抛出系统调用错误。您能否对此提出任何修改建议,或者如果我做错了什么:

 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

是否有更好的编写方法,或者是否有替代代码片段我也想尝试一下。谢谢你的时间。

我以前这样做过:

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());
        } 
    }
}

我的评论要点:

  • 您不需要创建文件:如果需要,StreamWriter 会创建文件,否则它将覆盖现有文件。
  • String.Join(separator, values) - 您将分隔符作为第二个参数。
  • 您还应该在使用完后调用 objWriter.Dispose()。

但是:

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 的问题。

这最终对我有用:

    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();
                               }
        }
}

}