我在visual studio 2008中使用c#和.NET 3.5。我想循环遍历存储在数据表中的结果集两次。我使用了以下脚本并成功循环一次。当我第二次循环它时,我得到一个例外(如下所示)。我该如何解决 ? 根据我的Java知识,我怀疑它有一些行指针到达最后一个位置。是否正确?
此C#脚本嵌入在SSIS中。不要担心SSIS。我很确定这个问题只与C#有关。请不要为此添加SSIS标记。
有关代码的注意事项 - 数据库表只有一个名为OneColumn的varchar列。它有 3行 - 一行,两行和三行。我选择此列并将其保存到名为“ResultSet”的Object变量中。我的C#脚本应该遍历行,加入它们并将它们显示为单个字符串。
之后,重复脚本。虽然您可能不需要它,但我也添加了SSIS图。
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Runtime;
using System.Windows.Forms;
using System.Xml;
using System.Data.OleDb;
namespace ST_bde893ffaa5d49efb7aed9d752cb900c.csproj
{
[System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
{
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
OleDbDataAdapter oleDA = new OleDbDataAdapter();
DataTable dt = new DataTable();
DataColumn col1 = null;
DataRow row = null;
string strCols = "";
oleDA.Fill(dt, Dts.Variables["ResultSet"].Value);
col1 = dt.Columns["OneColumn"];
int lastRow = dt.Rows.Count - 1;
for (int i = 0; i <= lastRow - 1; i++)
{
row = dt.Rows[i];
strCols = strCols + row[col1.Ordinal].ToString() + ", ";
}
row = dt.Rows[lastRow];
strCols = strCols + row[col1.Ordinal].ToString();
MessageBox.Show(strCols);
Dts.TaskResult = (int)ScriptResults.Success;
}
}
}
错误 -
Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.IndexOutOfRangeException: There is no row at position -1.
at System.Data.RBTree`1.GetNodeByIndex(Int32 userIndex)
at System.Data.RBTree`1.get_Item(Int32 index)
at System.Data.DataRowCollection.get_Item(Int32 index)
at ST_bde893ffaa5d49efb7aed9d752cb900c.csproj.ScriptMain.Main()
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()
EXTRA(你真的不需要了解SSIS) -
答案 0 :(得分:2)
-1指数可能来自最明显的地方是这两行的组合:
int lastRow = dt.Rows.Count - 1;
// followed by
row = dt.Rows[lastRow];
当dt.Rows.Count == 0
时,这会尝试访问dt.Rows[-1]
,这会告诉我第二次运行代码时,dt.Rows
没有填充。您可以通过将两个相关行包装在if语句中来修复即时错误,如
if (lastRow >= 0) {
row = dt.Rows[lastRow];
strCols = strCols + row[col1.Ordinal].ToString();
}
至于为什么你首先没有获得任何行?这可能是你最初预期的一个光标停留在最后。我将在故障排除中采取的下一步是确定实际运行时类型为Dts.Variables["ResultSet"].Value
的内容,然后查看相关文档以了解如何回放。