SSIS: Fehler bei einem Datenfluß

16/12/2008 - 13:10 von Christa Kurschat | Report spam
Hallo NG,

Ich habe von einem Kunden ein SSIS-Projekt übernommen. Dort werden Daten aus
Textdateien zunàchst in einen Stagingbereich geladen, anschließend von dort
in die Dimensionstabellen. Diese Daten werden historisiert. Im Prinzip kann
man sagen, daß sie versucht haben, einen SCD-Task nachzubauen.

In einer Skriptkomponente im Datenfluß werden einmal die Daten
durchgeschleust, zum anderen für den Update ein Buffer mit den Daten
gefüllt. Dieser Buffer endet in einer Update-Komponente.

Ich habe jetzt das Problem, daß anscheinend ein Dead-Lock entsteht.

Wenn ich das ausführe, werden ca. 8.000 DS verarbeitet und dann steht die
ganze Geschichte mit Locks.

Irgendwann, Stunden spàter, wenn ich nicht manuell abbreche, kommt dann
diese Fehlermeldung:

[SS_DST_DWH [16734]] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB
error has occurred. Error code: 0x80040E14. An OLE DB record is available.
Source: "Microsoft SQL Native Client" Hresult: 0x80040E14 Description:
"Cannot fetch a row from OLE DB provider "BULK" for linked server
"(null)".". An OLE DB record is available. Source: "Microsoft SQL Native
Client" Hresult: 0x80040E14 Description: "The OLE DB provider "BULK" for
linked server "(null)" reported an error. The provider did not give any
information about the error.". An OLE DB record is available. Source:
"Microsoft SQL Native Client" Hresult: 0x80040E14 Description: "Reading from
DTS buffer timed out.".

Ich habe überhaupt keine Idee, was ich wo àndern kann/muß, damit das Paket
mal durchlàuft.

Hier noch das Skript:

Codestart -

Public Class ScriptMain

Inherits UserComponent

Dim Var_SKOffset As Integer = 0

Dim Var_RecCounter As Integer = 0

Dim Var_LastValidFrom As Date

'ACHTUNG: DAMIT DIESE ROUTINE FUNKTIONIERT MUESSEN DIE DATEN

'IN ZEITLICH ABSTEIGENDER REIHENFOLGE UND NACH DEM PK SORTIERT EINTREFFEN:

'Beispiel: 10(PK)|2009(Datum), 10(PK)|2008(Datum),
10(PK)|2007(Datum),11(PK)|2008(Datum),11(PK)|2007(Datum)

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

Dim CDCChar As String

'Interner Zàhler...

Var_RecCounter = Var_RecCounter + 1

'Neuer SK wird berechnet

Var_SKOffset = Var_SKOffset + 1

If Row.MAXSK_IsNull Then Row.MAXSK = 0

Row.SK = Row.MAXSK + Var_SKOffset

'ChangeDataCapture FLAG merken

CDCChar = Trim(UCase(Row.FlgStatus))

'KORREKTUR: Wenn kein Eintrag im DWH - Aber CDC auf Update gesetzt ist

If Row.OLDSK_IsNull And (CDCChar = "U") Then CDCChar = "I"

'KORREKTUR: Wenn mind. ein Eintrag im DWH vorliegt - Aber CDC auf Insert
gesetzt ist

If (Not Row.OLDSK_IsNull) And (CDCChar = "I") Then CDCChar = "U"

'Ist bereits ein Eintrag im DWH...

If (Not Row.OLDSK_IsNull) AND (Row.ITEMCOUNT = Var_RecCounter) Then

'...dann muss dieser "Terminiert" werden.

UPDATEBuffer.AddRow()

UPDATEBuffer.OLDSK = Row.OLDSK

UPDATEBuffer.VALIDUNTIL = Row.MODIFYDATETIME

End If

If Var_RecCounter = 1 Then

If CDCChar = "D" Then

'Wenn der Datensatz "gelöscht" ist. Wird dieser direkt Terminiert.

Row.VALIDUNTIL = Row.MODIFYDATETIME

Row.FLAGEXPIRED = True

Else

'Erster Datensatz ist gültig bis "Unendlich"...

Row.VALIDUNTIL = Variables.PSCDDATEINFINITY

Row.FLAGEXPIRED = False

End If

Else

'Alle anderen bis zum Modify_Datum des Nachfolgers...

Row.VALIDUNTIL = Var_LastValidFrom

Row.FLAGEXPIRED = True

End If

Var_LastValidFrom = Row.MODIFYDATETIME

'Valid_From immer identisch zum Modifydatum

Row.VALIDFROM = Row.MODIFYDATETIME

'ACHTUNG: Bei der Migration kann das VALID_FROM auf einen bestimmten
Initialwert gesetzt werden

If Row.ITEMCOUNT = Var_RecCounter And Variables.PMIGRATION And
Variables.LINITSCDDATEBEGIN And Row.OLDSK_IsNull Then

'Ältester Eintrag : Row.ITEMCOUNT = Var_RecCounter

'Ist Migration : Variable P_MIGRATION

'Soll InitDatum gesetzt werden: Varaible L_INIT_SCD_DATE_BEGIN

'Kein Vorgànger im DWH : Row.OLDSK_NULL

Row.VALIDFROM = Variables.PSCDDATEBEGIN

End If

'Wenn das Quellsystem einen Datensatz löscht, wird diese Vermerkt

Row.FLAGDELETE = (CDCChar = "D")

'Wennn Gruppenende erreicht, Counter auf "0"

If Var_RecCounter >= Row.ITEMCOUNT Then Var_RecCounter = 0

End Sub

End Class

Code end

Mein Kollege, der sich ein bißchen mit .net auskennt, meint, daß da ein
UPDATBuffer.SetEndofRows gesetzt werden müßte. Ich weiß allerdings nicht,
wo. Direkt in der If-Anweisung nicht, da shatte ich versucht. 1. werden
trotzdem nicht alle DS verarbeitet (er steht an der gleichen Stelle) und 2.
wird dann nur 1 DS an die Updatekomponente gesendet statt wie bisher ca.
7000



Gruß

Christa
 

Lesen sie die antworten

#1 Willfried Faerber
16/12/2008 - 18:02 | Warnen spam
Hallo Christa,

aus der grossen Entfernung fàllt mir auf, dass Du über einen Linked Server
liesst. Gibt es einen Grund dafür?
Auf den ersten Blick sollte das funtionieren

Probiere es doch mal mit einer dirketen Verbindung zum Server.

Viele Grüsse
Willfried Fàrber SQL Server
"Christa Kurschat" wrote in message
news:
Hallo NG,

Ich habe von einem Kunden ein SSIS-Projekt übernommen. Dort werden Daten
aus Textdateien zunàchst in einen Stagingbereich geladen, anschließend von
dort in die Dimensionstabellen. Diese Daten werden historisiert. Im
Prinzip kann man sagen, daß sie versucht haben, einen SCD-Task
nachzubauen.

In einer Skriptkomponente im Datenfluß werden einmal die Daten
durchgeschleust, zum anderen für den Update ein Buffer mit den Daten
gefüllt. Dieser Buffer endet in einer Update-Komponente.

Ich habe jetzt das Problem, daß anscheinend ein Dead-Lock entsteht.

Wenn ich das ausführe, werden ca. 8.000 DS verarbeitet und dann steht die
ganze Geschichte mit Locks.

Irgendwann, Stunden spàter, wenn ich nicht manuell abbreche, kommt dann
diese Fehlermeldung:

[SS_DST_DWH [16734]] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB
error has occurred. Error code: 0x80040E14. An OLE DB record is available.
Source: "Microsoft SQL Native Client" Hresult: 0x80040E14 Description:
"Cannot fetch a row from OLE DB provider "BULK" for linked server
"(null)".". An OLE DB record is available. Source: "Microsoft SQL Native
Client" Hresult: 0x80040E14 Description: "The OLE DB provider "BULK" for
linked server "(null)" reported an error. The provider did not give any
information about the error.". An OLE DB record is available. Source:
"Microsoft SQL Native Client" Hresult: 0x80040E14 Description: "Reading
from DTS buffer timed out.".

Ich habe überhaupt keine Idee, was ich wo àndern kann/muß, damit das Paket
mal durchlàuft.

Hier noch das Skript:

Codestart -

Public Class ScriptMain

Inherits UserComponent

Dim Var_SKOffset As Integer = 0

Dim Var_RecCounter As Integer = 0

Dim Var_LastValidFrom As Date

'ACHTUNG: DAMIT DIESE ROUTINE FUNKTIONIERT MUESSEN DIE DATEN

'IN ZEITLICH ABSTEIGENDER REIHENFOLGE UND NACH DEM PK SORTIERT EINTREFFEN:

'Beispiel: 10(PK)|2009(Datum), 10(PK)|2008(Datum),
10(PK)|2007(Datum),11(PK)|2008(Datum),11(PK)|2007(Datum)

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

Dim CDCChar As String

'Interner Zàhler...

Var_RecCounter = Var_RecCounter + 1

'Neuer SK wird berechnet

Var_SKOffset = Var_SKOffset + 1

If Row.MAXSK_IsNull Then Row.MAXSK = 0

Row.SK = Row.MAXSK + Var_SKOffset

'ChangeDataCapture FLAG merken

CDCChar = Trim(UCase(Row.FlgStatus))

'KORREKTUR: Wenn kein Eintrag im DWH - Aber CDC auf Update gesetzt ist

If Row.OLDSK_IsNull And (CDCChar = "U") Then CDCChar = "I"

'KORREKTUR: Wenn mind. ein Eintrag im DWH vorliegt - Aber CDC auf Insert
gesetzt ist

If (Not Row.OLDSK_IsNull) And (CDCChar = "I") Then CDCChar = "U"

'Ist bereits ein Eintrag im DWH...

If (Not Row.OLDSK_IsNull) AND (Row.ITEMCOUNT = Var_RecCounter) Then

'...dann muss dieser "Terminiert" werden.

UPDATEBuffer.AddRow()

UPDATEBuffer.OLDSK = Row.OLDSK

UPDATEBuffer.VALIDUNTIL = Row.MODIFYDATETIME

End If

If Var_RecCounter = 1 Then

If CDCChar = "D" Then

'Wenn der Datensatz "gelöscht" ist. Wird dieser direkt Terminiert.

Row.VALIDUNTIL = Row.MODIFYDATETIME

Row.FLAGEXPIRED = True

Else

'Erster Datensatz ist gültig bis "Unendlich"...

Row.VALIDUNTIL = Variables.PSCDDATEINFINITY

Row.FLAGEXPIRED = False

End If

Else

'Alle anderen bis zum Modify_Datum des Nachfolgers...

Row.VALIDUNTIL = Var_LastValidFrom

Row.FLAGEXPIRED = True

End If

Var_LastValidFrom = Row.MODIFYDATETIME

'Valid_From immer identisch zum Modifydatum

Row.VALIDFROM = Row.MODIFYDATETIME

'ACHTUNG: Bei der Migration kann das VALID_FROM auf einen bestimmten
Initialwert gesetzt werden

If Row.ITEMCOUNT = Var_RecCounter And Variables.PMIGRATION And
Variables.LINITSCDDATEBEGIN And Row.OLDSK_IsNull Then

'Ältester Eintrag : Row.ITEMCOUNT = Var_RecCounter

'Ist Migration : Variable P_MIGRATION

'Soll InitDatum gesetzt werden: Varaible L_INIT_SCD_DATE_BEGIN

'Kein Vorgànger im DWH : Row.OLDSK_NULL

Row.VALIDFROM = Variables.PSCDDATEBEGIN

End If

'Wenn das Quellsystem einen Datensatz löscht, wird diese Vermerkt

Row.FLAGDELETE = (CDCChar = "D")

'Wennn Gruppenende erreicht, Counter auf "0"

If Var_RecCounter >= Row.ITEMCOUNT Then Var_RecCounter = 0

End Sub

End Class

Code end

Mein Kollege, der sich ein bißchen mit .net auskennt, meint, daß da ein
UPDATBuffer.SetEndofRows gesetzt werden müßte. Ich weiß allerdings nicht,
wo. Direkt in der If-Anweisung nicht, da shatte ich versucht. 1. werden
trotzdem nicht alle DS verarbeitet (er steht an der gleichen Stelle) und
2. wird dann nur 1 DS an die Updatekomponente gesendet statt wie bisher
ca. 7000



Gruß

Christa

Ähnliche fragen