【问题标题】:Looping a DataTable twice循环数据表两次
【发布时间】:2023-03-15 06:26:01
【问题描述】:

我在 Visual Studio 2008 中使用 c# 和 .NET 3.5。我想对存储在数据表中的结果集进行两次循环。我使用了以下脚本并成功循环了一次。当我第二次循环它时,我得到一个异常(如下所示)。我该如何解决 ? 根据我的 Java 知识,我怀疑它与行指针到达最后一个位置有关。正确与否?

这个 C# 脚本嵌入在 SSIS 中。不用担心 SSIS。我很确定这个问题只与 C# 有关。请不要为此添加 SSIS 标签。

关于代码的注释 - 一个数据库表只有一个名为 OneColumn 的 varchar 列。它有 3 行 - 一、二和三。我选择此列并将其保存到名为“ResultSet”的对象变量中。我的 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)-

【问题讨论】:

标签: c# sql-server ssis .net-3.5


【解决方案1】:

-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 的实际运行时类型是什么,然后查看相关文档以了解如何回退。

【讨论】:

  • 该文档有很多我相信很有用的内容。但是,如果我能找到要查看的特定部分,那就太好了。我还在学习 C# 的基础知识,需要一些帮助。
  • 类型名称是什么?
  • Dan,你说的 type name 是什么意思?所有变量类型都在我的代码中。
  • MessageBox.Show(Dts.Variables["ResultSet"].Value.GetType().Name)。这是我们必须倒带的结果集。 OleDbDataAdapter 的签名只指定了interface IDataReader,不能回退。但是,如果我们知道该值的类型名称,我们也许能够找到一种可以使光标倒回的方法。
  • 不幸的是,我认为这意味着这刚刚成为一个 SSIS 问题。 COM 连接的另一端有东西,我不知道是什么。您可以在 ssis 标签下发布一个新问题并在那里获得答案,或者根据数据集的大小,您可能更幸运地使用简单的List&lt;T&gt; 将结果缓存在内存中。
猜你喜欢
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
  • 2021-01-26
  • 1970-01-01
  • 2011-06-01
相关资源
最近更新 更多