2016-06-16 17 views
0

Es tut mir leid, wenn diese Frage eine Wiederholung ist. Ich habe eine System.Object Variable, wo ich Ergebnisse für eine Select-Abfrage speichern. Ich muss die Ergebnisse in eine flache Datei ausgeben, um sie weiter zu verarbeiten. Ich habe das folgende Stück Code, das für einige Sekunden funktioniert und dann den Systemaufruffehler auslöst. Können Sie mir bitte keine Änderungen an dieser vorschlagen oder wenn ich etwas tue, falsch:Geben Sie den System.Object-Variablenwert in SSD in eine flache Datei aus

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 

Gibt es einen besseren Weg, dies zu schreiben, oder wenn es alternative ein Codestück, um zu versuchen und ich möchte, dass. Vielen Dank für Ihre Zeit.

+0

1) Sie brauchen nicht die Datei zu erstellen: die Stream dies tun wird, falls erforderlich, sonst wird es eine vorhandene Datei überschreiben . 2) 'String.Join (Trennzeichen, Werte)' - Sie haben das Trennzeichen als zweites Argument. 3) Sie sollten 'objWriter.Dispose()' auch aufrufen, wenn Sie damit fertig sind. –

+0

Danke für die Erklärung. Für Ihren 2. Punkt (String.Join (Trennzeichen, Werte) - Sie haben das Trennzeichen als zweites Argument) Wie soll ich meinen Code ändern? – rvphx

+0

Ich habe eine Antwort gegeben, die diese Punkte hoffentlich anspricht. Es wäre wahrscheinlich hilfreich gewesen, wenn Sie die Details des Fehlers angegeben hätten - wenn Ihnen etwas mehr als "Systemaufruffehler" gegeben wurde. –

Antwort

1

Ich habe es auf diese Weise in der Vergangenheit getan:

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

Grundsätzlich ist die Variable in eine Transformation Script übergeben und dann die Daten an die Pipeline hinzuzufügen. Ab diesem Punkt können Sie eine Zielkomponente als normal verwenden und vermeiden, die Ausgabedatei zu erstellen und die Felder zu begrenzen.

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

Ich versuche, dies zu folgen, aber wenn ich das Skript ausführen, bekomme ich Fehler, sagen Spalte 'ColumnName' gehört nicht zu Tabelle. Wo gehe ich falsch? – rvphx

1

Die Punkte aus meinem Kommentar:

  • Sie brauchen nicht die Datei zu erstellen: die Stream dies tun wird, falls erforderlich, sonst wird es eine vorhandene Datei überschrieben werden soll.
  • String.Join (Trennzeichen, Werte) - Sie haben das Trennzeichen als zweites Argument.
  • Sie sollten objWriter.Dispose() auch aufrufen, wenn Sie es nicht mehr verwenden.

Aber:

  • A StringBuilder ist effizienter für eine große Zeichenfolge zu schaffen.
  • Sie können den gesamten Text auf einmal schreiben, indem Sie die Methode verwenden.
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 

Ich denke, dass Sie ein paar Zeilen mit den OleDbDataAdapter aus mehr zu tun, aber ich bin mit SSIS nicht vertraut.

Wenn Sie können, verwenden Sie Option Strict On - es hätte das Problem mit der String.Join für Sie aufgezeigt.

0

Dies ist, was für mich gearbeitet schließlich:

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

}