C# 当使用TransactionLevel.ReadUncommitted从准备好的语句将行从c插入MS Access时,排序似乎是关闭的

C# 当使用TransactionLevel.ReadUncommitted从准备好的语句将行从c插入MS Access时,排序似乎是关闭的,c#,ms-access,transactions,oledb,C#,Ms Access,Transactions,Oledb,我有一些c语言的代码,它使用准备好的语句将信息逐行写入access数据库。我正在使用OleDb和TransactionLevel.ReadUncommitted,因为有时我需要在提交数据之前查看数据 问题似乎是,在7个不同表中的1个表上,我从数据库检索记录的顺序与我输入的顺序不同。在我尝试使用它的4次中,大约有1次会发生这种情况,所以我似乎无法真正调试它 编辑 排序在这里很重要的原因是,我们正在将表转储到一个excel表中,该表与表中已有的数据相匹配。Order by可能会取得一些进展,但有一列

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

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

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

我倾向于将它作为预处理语句的insert命令的竞争条件,也就是说,要一次处理的访问太多了,所以它们会变得混乱

有人对此有什么想法吗?下面是我正在做的几个片段: 对不起,长度太长了,我尽量剪掉了,但还是把主要部件剪掉了

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

在populatemptable方法中,即使发生错误,您也在提交事务。这是你的本意吗


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

在Jet中,表的聚集索引物理顺序由主键决定,或者在没有PK的情况下,由随机选择的另一个键决定?靠发动机。但是,物理排序仅在压缩数据库文件.mdb、.mde、.accdb时发生。压缩之后或第一次压缩之前插入的行按日期/时间顺序插入。现在,Jet的DATETIME数据类型支持的最小时间颗粒是1秒,尽管在封面下,该值存储为双浮点,因此我想知道粒度是否不够精细,无法满足您的需要。但为什么要依赖于一台老旧发动机的这些记录不全的功能呢


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

为了简洁起见,删除了流程节点中的大部分代码,第二个命令基本上查询源表并检索数据以填充临时表。是的,事务已提交bcuz错误被抛出,表将立即被删除,并向用户发送消息我也删除了错误处理代码,因为我认为这不太重要。请澄清我从数据库检索的顺序与我输入的顺序不同。这是指处理表格的顺序,还是指记录的顺序?如果是后者,则不必担心,因为ORDER BY就是用于此目的的。表是动态创建的,因此字段的数量在运行时之前是未知的。所以我使用SELECT*,但现在我在构建表的同时构建SELECT查询。本质上,这正是我最终要做的,但这些知识很有帮助——谢谢!