0

我在 c# 中有一些代码,它使用准备好的语句将信息(逐行)写入访问数据库。我正在使用 OleDb 和 TransactionLevel.ReadUncommitted,因为有时我需要在提交之前查看数据。

问题似乎是在 7 个不同表中的 1 个上,我从数据库中检索记录的顺序与我放入它们的顺序不同。这种情况大约每 4 次我尝试使用它就会发生 1 次,所以我似乎无法调试它。

编辑 这里排序很重要的原因是我们将表格转储到一个与那里已经存在的数据相匹配的 Excel 工作表中。Order by 可能会取得一些进展,但是有一个列是按无法与工作表上的数据匹配的移动(即 N-NW)排序的。

我倾向于它是准备好的语句的插入命令的竞争条件(即有太多的访问权限一次处理,所以它们变得混乱)。

有人对此有任何想法吗?以下是我正在做的一些片段:(对不起长度,我试图尽可能多地剪掉,但仍然把主要组件拿出来)

protected override void PopulateTmpTable()
  {
    OleDbCommand objComm = null;
    try
    {
      objComm = new OleDbCommand("", mDbconn);
      ...
      //Begin SQL Transaction
      mTr = mDbconn.BeginTransaction(System.Data.IsolationLevel.ReadUncommitted);
      objComm.Transaction = mTr;
      //Start Populating Temp Table
      for (int i = 1; i <= mNrows; i++)
      {
        ...
        ProcessNode(objComm, node, approaches);
        ProcessNodeSummary(objComm, node);
      }
      ProcessSummary(objComm);
    }
    catch (Exception e) { }
    finally
    {
      if (mTr != null) mTr.Commit();
      if (objComm != null) objComm.Dispose();
    }
  }  //End Method PopulateTmpTable

  private void ProcessNode(OleDbCommand objComm, string node, List<string> approaches)
  {
    try
    {
      ...
      OleDbCommand objComm2 = new OleDbCommand("", mDbconn, mTr);
      for (int k = 0; k < MaxLegs; k++)
      {
        ...
            total = ProcessIterations(objComm, node, turning[m], m);
          }
          objComm.ExecuteNonQuery();
        }  //End if
      }  //End for
    }
    catch { }
  }  //End Method ProcessNode

private List<double> ProcessIterations(OleDbCommand objComm, string node, string turn, int m)
  {
    try
    {
      OleDbCommand objComm2 = new OleDbCommand("", mDbconn, mTr);
      OleDbDataReader objRead;
      objComm.Parameters["parameter"].Value = //Stuff (x2)
        for (int j = 0; j < mIterations; j++)
        {
          ...
          objComm2.CommandText = "SELECT ROUND(AVG(Delay),1), COUNT(VehNo) FROM [TABLE] WHERE NodeNo=" + node + " AND Movement='" + turn + "' AND Iteration=" + mIterationValue[j] + mFilter[1];
          objRead = objComm2.ExecuteReader();
          objRead.Read();
          try
          {
              objComm.Parameters["more parameters"].Value = objRead[0];
              ...
          }
          catch { }
          objRead.Close();
        }//End for
        ...
        objComm.ExecuteNonQuery();
        objComm2.CommandText = "UPDATE " + mTmptable + " SET ave=" + avg + ",minimum=" + mMini[m] + ",maximum=" + mMaxi[m] + ",dev=" + stDev + " WHERE node='" + node + "' AND movement = '" + temp + "';";
        objComm2.ExecuteNonQuery();
      }
    }
    catch{}
    return mTotal;
  }  //End Function ProcessIterations
4

2 回答 2

0

在您的 PopulateTmpTable() 方法中,即使发生错误,您也正在提交事务。那是你的意图吗?

在 ProcessNode() 中,您传入一个命令对象,创建一个新对象,然后使用传入的那个?

于 2009-01-17T00:56:34.397 回答
0

在 Jet 中,表的聚集索引(物理排序)由 PRIMARY KEY 确定,或者在没有 PK 的情况下,由引擎选择(随机?)另一个键。但是,物理排序仅在压缩数据库文件(.mdb、.mde、.accdb)时发生。在压缩之后(或在第一个压缩之前)插入的行按日期/时间顺序插入。现在,Jet 的 DATETIME 数据类型支持的最小时间粒度是一秒,尽管在幕后该值存储为双浮点数,因此我想知道粒度是否不足以满足您的目的。但是,为什么要依赖旧引擎的记录不充分的功能……?

如果您知道插入行的顺序,则在数据库中对其进行建模,例如使用 INTEGER 列来存储您的应用程序负责为其提供值的序列号。并在列上放置一个 UNIQUE 约束,只是为了确定。然后只需在查询中按您的序列列排序。

于 2009-01-20T09:12:30.970 回答