Jegyzet
Az oldalhoz való hozzáférés engedélyezést igényel. Próbálhatod be jelentkezni vagy könyvtárat váltani.
Az oldalhoz való hozzáférés engedélyezést igényel. Megpróbálhatod a könyvtár váltását.
A következőkre vonatkozik:SQL Server
SSIS integrációs futtatókörnyezet az Azure Data Factory-ban
A hibakimenetnek nevezett speciális IDTSOutput100 objektumok hozzáadhatók az összetevőkhöz, hogy az összetevő átirányítsa azokat a sorokat, amelyeket a végrehajtás során nem tud feldolgozni. Az összetevőkkel kapcsolatos problémák általában hibákként vagy csonkolásként vannak kategorizálva, és az egyes összetevőkre jellemzőek. A hibakimeneteket biztosító összetevők rugalmasságot biztosítanak az összetevő felhasználói számára a hibafeltételek kezeléséhez a hibasorok eredményhalmazból való szűrésével, az összetevő meghibásodásával, ha probléma merül fel, vagy figyelmen kívül hagyják a hibákat és folytatják a problémát.
Az összetevők hibakimeneteinek implementálásához és támogatásához először UsesDispositions kell állítania az összetevő tulajdonságát. Ezután hozzá kell adnia egy kimenetet ahhoz az összetevőhöz, amelynek tulajdonsága IsErrorOutigaz. Végül az összetevőnek olyan kódot kell tartalmaznia, amely hibák vagy csonkolások esetén átirányítja a sorokat a hibakimenethez. Ez a témakör ismerteti ezt a három lépést, és ismerteti a szinkron és az aszinkron hibakimenetek közötti különbségeket.
Hibakimenet létrehozása
A hibakimenet létrehozásához meghívja Newa OutputCollection metódust, majd az IsErrorOut új kimenet tulajdonságát igaz értékre állítja. Ha a kimenet aszinkron, semmi mást nem kell tenni a kimeneten. Ha a kimenet szinkron, és van egy másik kimenet is, amely ugyanahhoz a bemenethez szinkronizálódik, akkor a tulajdonságokat és ExclusionGroup a SynchronousInputID tulajdonságokat is be kell állítania. Mindkét tulajdonságnak ugyanazokkal az értékekkel kell rendelkeznie, mint a többi kimenetnek, amely szinkronizálva van ugyanahhoz a bemenethez. Ha ezek a tulajdonságok nem nulla értékre vannak beállítva, a bemenet által biztosított sorok mindkét kimenetre lesznek elküldve, amelyek szinkronban vannak a bemenettel.
Amikor egy összetevő hibát vagy csonkolást tapasztal a végrehajtás során, a bemenet vagy kimenet, illetve a bemeneti vagy kimeneti oszlop beállításai ErrorRowDisposition és TruncationRowDisposition tulajdonságai alapján halad tovább, ahol a hiba történt. Ezeknek a tulajdonságoknak az értékét alapértelmezés szerint a következőre RD_NotUsedkell állítani: . Ha az összetevő hibakimenete egy alsóbb rétegbeli összetevőhöz csatlakozik, ezt a tulajdonságot az összetevő felhasználója állítja be, és lehetővé teszi a felhasználó számára, hogy szabályozza, hogyan kezeli az összetevő a hibát vagy csonkolást.
Hibaoszlopok feltöltése
Hibakimenet létrehozásakor az adatfolyam-feladat automatikusan két oszlopot ad hozzá a kimeneti oszlopgyűjteményhez. Ezeket az oszlopokat az összetevők használják a hibát vagy csonkolást okozó oszlop azonosítójának megadására, valamint az összetevőspecifikus hibakód megadására. Ezek az oszlopok automatikusan jönnek létre, de az oszlopokban található értékeket az összetevőnek kell beállítania.
Az oszlopok értékeinek beállítására használt módszer attól függ, hogy a hibakimenet szinkron vagy aszinkron-e. A szinkron kimenettel rendelkező összetevők meghívják a DirectErrorRow metódust, amelyet a következő szakaszban részletesebben ismertetünk, és paraméterként adja meg a hibakódot és a hibaoszlop értékeit. Az aszinkron kimenettel rendelkező összetevők két lehetőség közül választhatnak az oszlopok értékeinek beállításához. Meghívhatják a SetErrorInfo kimeneti puffer metódusát, és megadhatja az értékeket, vagy megkereshetik a hibaoszlopokat a pufferben az oszlopok értékeinek közvetlen használatával FindColumnByLineageID és beállításával. Előfordulhat azonban, hogy az oszlopok neve módosult, vagy a kimeneti oszlopgyűjteményben lévő helyük módosult, az utóbbi módszer nem biztos benne. A SetErrorInfo metódus automatikusan beállítja a hibaoszlopokban lévő értékeket anélkül, hogy manuálisan kellene megkeresnie őket.
Ha egy adott hibakódnak megfelelő hibaleírást kell beszereznie, az összetevő tulajdonságán keresztül elérhető felület metódusát GetErrorDescription használhatja.IDTSComponentMetaData100ComponentMetaData
Az alábbi példakód egy olyan összetevőt mutat be, amely bemenettel és két kimenettel rendelkezik, beleértve a hibakimenetet is. Az első példa bemutatja, hogyan hozható létre a bemenettel szinkron hibakimenet. A második példa bemutatja, hogyan hozható létre aszinkron hibakimenet.
public override void ProvideComponentProperties()
{
// Specify that the component has an error output.
ComponentMetaData.UsesDispositions = true;
// Create the input.
IDTSInput100 input = ComponentMetaData.InputCollection.New();
input.Name = "Input";
input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed;
input.ErrorOrTruncationOperation = "A string describing the possible error or truncation that may occur during execution.";
// Create the default output.
IDTSOutput100 output = ComponentMetaData.OutputCollection.New();
output.Name = "Output";
output.SynchronousInputID = input.ID;
output.ExclusionGroup = 1;
// Create the error output.
IDTSOutput100 errorOutput = ComponentMetaData.OutputCollection.New();
errorOutput.IsErrorOut = true;
errorOutput.Name = "ErrorOutput";
errorOutput.SynchronousInputID = input.ID;
errorOutput.ExclusionGroup = 1;
}
Public Overrides Sub ProvideComponentProperties()
' Specify that the component has an error output.
ComponentMetaData.UsesDispositions = True
Dim input As IDTSInput100 = ComponentMetaData.InputCollection.New
' Create the input.
input.Name = "Input"
input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed
input.ErrorOrTruncationOperation = "A string describing the possible error or truncation that may occur during execution."
' Create the default output.
Dim output As IDTSOutput100 = ComponentMetaData.OutputCollection.New
output.Name = "Output"
output.SynchronousInputID = input.ID
output.ExclusionGroup = 1
' Create the error output.
Dim errorOutput As IDTSOutput100 = ComponentMetaData.OutputCollection.New
errorOutput.IsErrorOut = True
errorOutput.Name = "ErrorOutput"
errorOutput.SynchronousInputID = input.ID
errorOutput.ExclusionGroup = 1
End Sub
Az alábbi példakód egy aszinkron hibakimenetet hoz létre.
public override void ProvideComponentProperties()
{
// Specify that the component has an error output.
ComponentMetaData.UsesDispositions = true;
// Create the input.
IDTSInput100 input = ComponentMetaData.InputCollection.New();
input.Name = "Input";
input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed;
input.ErrorOrTruncationOperation = "A string describing the possible error or truncation that may occur during execution.";
// Create the default output.
IDTSOutput100 output = ComponentMetaData.OutputCollection.New();
output.Name = "Output";
// Create the error output.
IDTSOutput100 errorOutput = ComponentMetaData.OutputCollection.New();
errorOutput.Name = "ErrorOutput";
errorOutput.IsErrorOut = true;
}
Public Overrides Sub ProvideComponentProperties()
' Specify that the component has an error output.
ComponentMetaData.UsesDispositions = True
' Create the input.
Dim input As IDTSInput100 = ComponentMetaData.InputCollection.New
' Create the default output.
input.Name = "Input"
input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed
input.ErrorOrTruncationOperation = "A string describing the possible error or truncation that may occur during execution."
' Create the error output.
Dim output As IDTSOutput100 = ComponentMetaData.OutputCollection.New
output.Name = "Output"
Dim errorOutput As IDTSOutput100 = ComponentMetaData.OutputCollection.New
errorOutput.Name = "ErrorOutput"
errorOutput.IsErrorOut = True
End Sub
Sor átirányítása hibakimenetre
Miután hibakimenetet adott hozzá egy összetevőhöz, meg kell adnia az összetevőre vonatkozó hiba- vagy csonkítási feltételeket kezelő kódot, és átirányítja a hiba- vagy csonkítási sorokat a hibakimenetre. Ezt kétféleképpen teheti meg, attól függően, hogy a hibakimenet szinkron vagy aszinkron.
Sor átirányítása szinkron kimenetekkel
A sorokat a rendszer az osztály metódusának DirectErrorRow meghívásával PipelineBuffer küldi el a szinkron kimenetekre. A metódushívás paraméterként tartalmazza a hibakimenet azonosítóját, az összetevő által definiált hibakódot és annak az oszlopnak az indexét, amelyet az összetevő nem tudott feldolgozni.
Az alábbi példakód bemutatja, hogyan irányíthat egy sort egy pufferben szinkron hibakimenetre a DirectErrorRow metódus használatával.
public override void ProcessInput(int inputID, PipelineBuffer buffer)
{
IDTSInput100 input = ComponentMetaData.InputCollection.GetObjectByID(inputID);
// This code sample assumes the component has two outputs, one the default,
// the other the error output. If the errorOutputIndex returned from GetErrorOutputInfo
// is 0, then the default output is the second output in the collection.
int defaultOutputID = -1;
int errorOutputID = -1;
int errorOutputIndex = -1;
GetErrorOutputInfo(ref errorOutputID,ref errorOutputIndex);
if (errorOutputIndex == 0)
defaultOutputID = ComponentMetaData.OutputCollection[1].ID;
else
defaultOutputID = ComponentMetaData.OutputCollection[0].ID;
while (buffer.NextRow())
{
try
{
// TODO: Implement code to process the columns in the buffer row.
// Ideally, your code should detect potential exceptions before they occur, rather
// than having a generic try/catch block such as this.
// However, because the error or truncation implementation is specific to each component,
// this sample focuses on actually directing the row, and not a single error or truncation.
// Unless an exception occurs, direct the row to the default
buffer.DirectRow(defaultOutputID);
}
catch
{
// Yes, has the user specified to redirect the row?
if (input.ErrorRowDisposition == DTSRowDisposition.RD_RedirectRow)
{
// Yes, direct the row to the error output.
// TODO: Add code to include the errorColumnIndex.
buffer.DirectErrorRow(errorOutputID, 0, errorColumnIndex);
}
else if (input.ErrorRowDisposition == DTSRowDisposition.RD_FailComponent || input.ErrorRowDisposition == DTSRowDisposition.RD_NotUsed)
{
// No, the user specified to fail the component, or the error row disposition was not set.
throw new Exception("An error occurred, and the DTSRowDisposition is either not set, or is set to fail component.");
}
else
{
// No, the user specified to ignore the failure so
// direct the row to the default output.
buffer.DirectRow(defaultOutputID);
}
}
}
}
Public Overrides Sub ProcessInput(ByVal inputID As Integer, ByVal buffer As PipelineBuffer)
Dim input As IDTSInput100 = ComponentMetaData.InputCollection.GetObjectByID(inputID)
' This code sample assumes the component has two outputs, one the default,
' the other the error output. If the errorOutputIndex returned from GetErrorOutputInfo
' is 0, then the default output is the second output in the collection.
Dim defaultOutputID As Integer = -1
Dim errorOutputID As Integer = -1
Dim errorOutputIndex As Integer = -1
GetErrorOutputInfo(errorOutputID, errorOutputIndex)
If errorOutputIndex = 0 Then
defaultOutputID = ComponentMetaData.OutputCollection(1).ID
Else
defaultOutputID = ComponentMetaData.OutputCollection(0).ID
End If
While buffer.NextRow
Try
' TODO: Implement code to process the columns in the buffer row.
' Ideally, your code should detect potential exceptions before they occur, rather
' than having a generic try/catch block such as this.
' However, because the error or truncation implementation is specific to each component,
' this sample focuses on actually directing the row, and not a single error or truncation.
' Unless an exception occurs, direct the row to the default
buffer.DirectRow(defaultOutputID)
Catch
' Yes, has the user specified to redirect the row?
If input.ErrorRowDisposition = DTSRowDisposition.RD_RedirectRow Then
' Yes, direct the row to the error output.
' TODO: Add code to include the errorColumnIndex.
buffer.DirectErrorRow(errorOutputID, 0, errorColumnIndex)
Else
If input.ErrorRowDisposition = DTSRowDisposition.RD_FailComponent OrElse input.ErrorRowDisposition = DTSRowDisposition.RD_NotUsed Then
' No, the user specified to fail the component, or the error row disposition was not set.
Throw New Exception("An error occurred, and the DTSRowDisposition is either not set, or is set to fail component.")
Else
' No, the user specified to ignore the failure so
' direct the row to the default output.
buffer.DirectRow(defaultOutputID)
End If
End If
End Try
End While
End Sub
Sor átirányítása aszinkron kimenetekkel
Ahelyett, hogy sorokat irányítanának egy kimenetre, ahogyan a szinkron hibakimenetek esetében is, az aszinkron kimenettel rendelkező összetevők egy sort küldenek egy hibakimenethez úgy, hogy explicit módon hozzáadnak egy sort a kimenethez PipelineBuffer. Az aszinkron hibakimeneteket használó összetevők implementálásához oszlopokat kell hozzáadni a hibakimenethez, amelyeket az alsóbb rétegbeli összetevők biztosítanak, és gyorsítótárazva kell a kimeneti puffert az összetevőnek a PrimeOutput metódus során megadott hibakimenethez. Az összetevők aszinkron kimenetekkel történő implementálásának részleteit az Egyéni átalakítási összetevő aszinkron kimenetekkel történő fejlesztése című témakör ismerteti. Ha az oszlopok nincsenek explicit módon hozzáadva a hibakimenethez, a kimeneti pufferhez hozzáadott puffersor csak a két hibaoszlopot tartalmazza.
Ha egy sort aszinkron hibakimenetbe szeretne küldeni, fel kell vennie egy sort a hibakimeneti pufferbe. Előfordulhat, hogy már hozzáadtak egy sort a hibamentes kimeneti pufferhez, és ezt a sort el kell távolítania a RemoveRow metódus használatával. Ezután beállítja a kimeneti pufferoszlopok értékeit, és végül meghívja a SetErrorInfo metódust az összetevőspecifikus hibakód és a hibaoszlop értékének megadásához.
Az alábbi példa bemutatja, hogyan használható hibakimenet egy összetevőhöz aszinkron kimenetekkel. A szimulált hiba bekövetkezésekor az összetevő hozzáad egy sort a hibakimeneti pufferhez, átmásolja a korábban a hibakimeneti pufferhez hozzáadott értékeket a hibakimeneti pufferbe, eltávolítja a nem hiba kimeneti pufferhez hozzáadott sort, és végül a metódus meghívásával beállítja a hibakódot és a SetErrorInfo hibaoszlop értékeit.
int []columnIndex;
int errorOutputID = -1;
int errorOutputIndex = -1;
public override void PreExecute()
{
IDTSOutput100 defaultOutput = null;
this.GetErrorOutputInfo(ref errorOutputID, ref errorOutputIndex);
foreach (IDTSOutput100 output in ComponentMetaData.OutputCollection)
{
if (output.ID != errorOutputID)
defaultOutput = output;
}
columnIndex = new int[defaultOutput.OutputColumnCollection.Count];
for(int col =0 ; col < defaultOutput.OutputColumnCollection.Count; col++)
{
IDTSOutputColumn100 column = defaultOutput.OutputColumnCollection[col];
columnIndex[col] = BufferManager.FindColumnByLineageID(defaultOutput.Buffer, column.LineageID);
}
}
public override void PrimeOutput(int outputs, int[] outputIDs, PipelineBuffer[] buffers)
{
for( int x=0; x < outputs; x++ )
{
if (outputIDs[x] == errorOutputID)
this.errorBuffer = buffers[x];
else
this.defaultBuffer = buffers[x];
}
int rows = 100;
Random random = new Random(System.DateTime.Now.Millisecond);
for (int row = 0; row < rows; row++)
{
try
{
defaultBuffer.AddRow();
for (int x = 0; x < columnIndex.Length; x++)
defaultBuffer[columnIndex[x]] = random.Next();
// Simulate an error.
if ((row % 2) == 0)
throw new Exception("A simulated error.");
}
catch
{
// Add a row to the error buffer.
errorBuffer.AddRow();
// Get the values from the default buffer
// and copy them to the error buffer.
for (int x = 0; x < columnIndex.Length; x++)
errorBuffer[columnIndex[x]] = defaultBuffer[columnIndex[x]];
// Set the error information.
errorBuffer.SetErrorInfo(errorOutputID, 1, 0);
// Remove the row that was added to the default buffer.
defaultBuffer.RemoveRow();
}
}
if (defaultBuffer != null)
defaultBuffer.SetEndOfRowset();
if (errorBuffer != null)
errorBuffer.SetEndOfRowset();
}
Private columnIndex As Integer()
Private errorOutputID As Integer = -1
Private errorOutputIndex As Integer = -1
Public Overrides Sub PreExecute()
Dim defaultOutput As IDTSOutput100 = Nothing
Me.GetErrorOutputInfo(errorOutputID, errorOutputIndex)
For Each output As IDTSOutput100 In ComponentMetaData.OutputCollection
If Not (output.ID = errorOutputID) Then
defaultOutput = output
End If
Next
columnIndex = New Integer(defaultOutput.OutputColumnCollection.Count) {}
Dim col As Integer = 0
While col < defaultOutput.OutputColumnCollection.Count
Dim column As IDTSOutputColumn100 = defaultOutput.OutputColumnCollection(col)
columnIndex(col) = BufferManager.FindColumnByLineageID(defaultOutput.Buffer, column.LineageID)
System.Math.Min(System.Threading.Interlocked.Increment(col),col-1)
End While
End Sub
Public Overrides Sub PrimeOutput(ByVal outputs As Integer, ByVal outputIDs As Integer(), ByVal buffers As PipelineBuffer())
Dim x As Integer = 0
While x < outputs
If outputIDs(x) = errorOutputID Then
Me.errorBuffer = buffers(x)
Else
Me.defaultBuffer = buffers(x)
End If
System.Math.Min(System.Threading.Interlocked.Increment(x),x-1)
End While
Dim rows As Integer = 100
Dim random As Random = New Random(System.DateTime.Now.Millisecond)
Dim row As Integer = 0
While row < rows
Try
defaultBuffer.AddRow
Dim x As Integer = 0
While x < columnIndex.Length
defaultBuffer(columnIndex(x)) = random.Next
System.Math.Min(System.Threading.Interlocked.Increment(x),x-1)
End While
' Simulate an error.
If (row Mod 2) = 0 Then
Throw New Exception("A simulated error.")
End If
Catch
' Add a row to the error buffer.
errorBuffer.AddRow
' Get the values from the default buffer
' and copy them to the error buffer.
Dim x As Integer = 0
While x < columnIndex.Length
errorBuffer(columnIndex(x)) = defaultBuffer(columnIndex(x))
System.Math.Min(System.Threading.Interlocked.Increment(x),x-1)
End While
' Set the error information.
errorBuffer.SetErrorInfo(errorOutputID, 1, 0)
' Remove the row that was added to the default buffer.
defaultBuffer.RemoveRow
End Try
System.Math.Min(System.Threading.Interlocked.Increment(row),row-1)
End While
If Not (defaultBuffer Is Nothing) Then
defaultBuffer.SetEndOfRowset
End If
If Not (errorBuffer Is Nothing) Then
errorBuffer.SetEndOfRowset
End If
End Sub