none
SSIS Skriptkomponente Laufzeitfehler RRS feed

  • Frage

  • Moin moin,

    in mein ETL-Prozess versuche ich von der Folgende Tabelle:

    Tabelle A

    Concat auf number machen. Das Ergebnis soll so aussehen:

    Ergebnis

    dafür habe ich nach diesem Beispiel  einen SSIS Skriptkomponente erstellt.

    erhalte ich Folgende Fehler Meldung:

    Skriptkomponente Laufzeitfehler

    Skriptkomponente Laufzeitfehler 

    kann jemand vielleicht mir helfen?

    VG

    Fabi

     

    Mittwoch, 11. Mai 2016 14:47

Antworten

  • Hi,

    ich persönlich würde schauen, dass ich mir meine Datenquelle(n), wenn möglich, per SQL aufbaue und die dann verarbeite (dort könnte man dann bspw. auch sowas wie das o.g. SQL Statement einbringen, dann hätte man das Problem gar nicht erst).

    Angenommen, deine Daten sind für dein Skript korrekt vorsortiert (sonst wird das eh nix), könntest Du dir eine Zählervariable einbauen und die dann abfragen.

    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
    
        bool initialRow = true;
        string GUID = "";
        string TEXT = "";
        int counter = 0;
    
        public override void PreExecute()
        {
            base.PreExecute();
    
        }
        public override void Input_ProcessInput(InputBuffer Buffer)
        {
    
            while (Buffer.NextRow())
            {
                Input_ProcessInputRow(Buffer);
               initialRow = false;
            }
    
            if (Buffer.EndOfRowset())
            {
    
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
            }
        }
    
        public override void PostExecute()
        {
            base.PostExecute();
    
        }
    
        public override void Input_ProcessInputRow(InputBuffer Row)
        {
            if (initialRow)
            {
                OutputBuffer.AddRow();
                GUID = Row.newguid;
                TEXT = Row.newtext;
                counter = 1;
            }
            else if ((!initialRow) & (GUID != Row.newguid))
            {
                counter = 1;
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
                OutputBuffer.AddRow();
    
                GUID = Row.newguid;
                TEXT = Row.newtext;
            }
            else if ((!initialRow) & (GUID == Row.newguid))
            {
                if( counter <= 10 )
                {
                    TEXT += "," + Row.newtext;
                    counter += 1;
                }
            }
        }
    
        public override void CreateNewOutputRows()
        {
    
        }
    
    }


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 13. Mai 2016 17:39
    Moderator

Alle Antworten

  • Hallo Fabi,

    wie groß sind denn die Daten in dem Feld und wie ist das Feld in der neuen Tabelle deklariert? (In erster Linie die Feldgröße)


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 11. Mai 2016 15:08
    Moderator
  • Hi Stefan,

    danke für die Rückmeldung.

    GUID varchar(36)
    Text nvarchar(40)

    sowohl quelle als auch den ziel. 

    das hier ist mein Script.

    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
    
        bool initialRow = true;      
        string GUID = "";        
        string TEXT = "";        
    
        public override void PreExecute()
        {
            base.PreExecute();
    
        }
        public override void Input_ProcessInput(InputBuffer Buffer)
        {
    
            while (Buffer.NextRow())
            {
                Input_ProcessInputRow(Buffer);
               initialRow = false;
            }
    
            if (Buffer.EndOfRowset())
            {
    
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
            }
        }
    
        public override void PostExecute()
        {
            base.PostExecute();
    
        }
    
        public override void Input_ProcessInputRow(InputBuffer Row)
        {
    
            if (initialRow)
            {
    
                OutputBuffer.AddRow();
    
                GUID = Row.newguid;
                TEXT = Row.newtext;
            }
            else if ((!initialRow) & (GUID != Row.newguid))
            {
    
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
                OutputBuffer.AddRow();
    
                GUID = Row.newguid;
                TEXT = Row.newtext;
            }
            else if ((!initialRow) & (GUID == Row.newguid))
            {
    
                TEXT += "," + Row.newtext;
            }
        }
    
        public override void CreateNewOutputRows()
        {
    
        }
    
    }
    

    VG

    Mittwoch, 11. Mai 2016 15:35
  • Hallo Stefan,

    nochmal dank,

    gute hinweis, mein Fehler war das ich in der neuen Tabelle auch gleiches Feldgröße genommen hatte.

    also Feldgröße  geändert und schon Funktioniert ;-) 

    Danke

    Mittwoch, 11. Mai 2016 15:48
  • Hallo Fabi,

    und Du bist sicher, dass der neue, zusammengesetzte Inhalt nicht größer als 40 Zeichen ist?


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 11. Mai 2016 15:48
    Moderator
  • moin Stefan,

    ich habe das Feldgröße auf 255 Zeichen gesetzt. es Funktioniert.

    nun taucht ne andere Problem. bei manchen Datennetzen sind die Inhalt des Feldes "TEXT" mehr als 100 Werte.

    Also AA,BB,CC,DD........

    wie kann ich die Anzahl z.B. auf 10 setzen. musste man eventuelle im Script anpassen ?!

    VG

    Donnerstag, 12. Mai 2016 07:48
  • Hi,

    irgendwo hast Du ja ein SQL Statement, dass die Datensätze ausliest. Dort solltest Du dann bspw. mit

    SELECT TOP 10 ...

    arbeiten.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 12. Mai 2016 09:57
    Moderator
  • Hi Stefan,

    danke, ich glaube ich habe mich falsch ausgedrückt. In der neuen Tabelle über den Script landen die Werte aus dem Quelle in dem Feld (hier das Feld TEXT) hintereinander mit Komma getrennt.

    Egebnis 

    wenn ich das Feld "text" auf MAX setze passen nicht alle werte in dem Feld, deshalb wollte nur 10 Werte importieren.

    VG

    Fabi

    Donnerstag, 12. Mai 2016 13:56
  • Hi,

    bei nvarchar( MAX ) passt nicht alles in das Feld?

    So oder so: Der Weg ist derselbe: Du hast irgendwo ein SQL Statement, welches die Werte für die zusammengesetzten Texte ausliest. Und das solltest Du per TOP 10 begrenzen.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 12. Mai 2016 14:28
    Moderator
  • Oder Du fragst die aktuelle Länge des Inhalts ab. Wenn es nicht mehr passen würde, machst Du nichts mehr.

    Einen schönen Tag noch, Christoph -- Data Platform MVP - http://www.insidesql.org/blogs/cmu

    Freitag, 13. Mai 2016 08:36
  • Hi Stefan,

    nein Leider mit nvarchar(MAX) passt auch nicht.

    mit top (x) kriege ich nur x Datensätze (siehe Anhang) 

    top3

    das Ergebnis der Select top (3) aus der Tabelle ist nur erste drei Datensätze.

    Ich will aber zur jeden "GUID"  x-werte  in dem Feld TEXT.

    top3 auf text 

    in dem Beispiel (unten) schneidet die Werte nach 100 Zeichen. 

    WITH UniqueTeachers AS
    (
     SELECT  DISTINCT Teacher
     FROM  TeacherStudentTable
    )
    SELECT  Teacher
    ,   Students = STUFF((
          SELECT  ',' + Student
          FROM  TeacherStudentTable
          WHERE  Teacher = UniqueTeachers.Teacher
          ORDER BY Student
          FOR XML PATH(''), TYPE).value('.','varchar(100)'), 1, 1, '')
    FROM  UniqueTeachers
    ORDER BY Teacher

    aber mein Skriptkomponente läuft auf dem Fehler, weil die Inhalte größer als ausgabefeld sind :-)

    VG

    Freitag, 13. Mai 2016 10:12
  • Hi,

    ich versteh dein Problem nicht.

    WITH UniqueTeachers AS
    (
     SELECT  DISTINCT Teacher
     FROM  TeacherStudentTable
    )
    SELECT  Teacher
    ,   Students = STUFF((
          SELECT TOP 10 ',' + Student
          FROM  TeacherStudentTable
          WHERE  Teacher = UniqueTeachers.Teacher
          ORDER BY Student
          FOR XML PATH(''), TYPE).value('.','varchar(100)'), 1, 1, '')
    FROM  UniqueTeachers
    ORDER BY Teacher


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 13. Mai 2016 10:32
    Moderator
  • Hallo Chrsitoph,

    das ist mein Problem, mit C# bin ich nicht so vertraut :-)

    Ich muss irgenwie im Script definieren können, dass wenn das Ergebnis größer als 255 Zeichen ist, diese abzuschneiden.

    VG

    Freitag, 13. Mai 2016 12:12
  • Hallo Stefan,

    ich kann kein T-SQL Query verwenden, da ich in mein ETL Prozess mehrere Tabellen verarbeite und rechen..

    das ist ein Teil der ETL als Beispiel :-)

    ETL 

    VG

    Freitag, 13. Mai 2016 12:15
  • Hi,

    ich persönlich würde schauen, dass ich mir meine Datenquelle(n), wenn möglich, per SQL aufbaue und die dann verarbeite (dort könnte man dann bspw. auch sowas wie das o.g. SQL Statement einbringen, dann hätte man das Problem gar nicht erst).

    Angenommen, deine Daten sind für dein Skript korrekt vorsortiert (sonst wird das eh nix), könntest Du dir eine Zählervariable einbauen und die dann abfragen.

    using System;
    using System.Data;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    
    [Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
    public class ScriptMain : UserComponent
    {
    
        bool initialRow = true;
        string GUID = "";
        string TEXT = "";
        int counter = 0;
    
        public override void PreExecute()
        {
            base.PreExecute();
    
        }
        public override void Input_ProcessInput(InputBuffer Buffer)
        {
    
            while (Buffer.NextRow())
            {
                Input_ProcessInputRow(Buffer);
               initialRow = false;
            }
    
            if (Buffer.EndOfRowset())
            {
    
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
            }
        }
    
        public override void PostExecute()
        {
            base.PostExecute();
    
        }
    
        public override void Input_ProcessInputRow(InputBuffer Row)
        {
            if (initialRow)
            {
                OutputBuffer.AddRow();
                GUID = Row.newguid;
                TEXT = Row.newtext;
                counter = 1;
            }
            else if ((!initialRow) & (GUID != Row.newguid))
            {
                counter = 1;
                OutputBuffer.newguid = GUID;
                OutputBuffer.newtext = TEXT;
                OutputBuffer.AddRow();
    
                GUID = Row.newguid;
                TEXT = Row.newtext;
            }
            else if ((!initialRow) & (GUID == Row.newguid))
            {
                if( counter <= 10 )
                {
                    TEXT += "," + Row.newtext;
                    counter += 1;
                }
            }
        }
    
        public override void CreateNewOutputRows()
        {
    
        }
    
    }


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Freitag, 13. Mai 2016 17:39
    Moderator
  • Moin Stefan,

    danke, mit der Zähler-variable  Funktioniert. genau das wollte ich.

    VG

    Fabi

    Dienstag, 17. Mai 2016 09:01