При вставке строк в MS Access из c # с использованием TransactionLevel.ReadUncommitted из подготовленного оператора упорядочение кажется отключенным - PullRequest
0 голосов
/ 17 января 2009

У меня есть код на c #, который записывает информацию (строка за строкой) в базу данных доступа, используя подготовленные операторы. Я использую OleDb и TransactionLevel.ReadUncommitted, потому что иногда мне нужно просмотреть данные перед их фиксацией.

Кажется, проблема в том, что в 1 из 7 разных таблиц порядок, в котором я извлекаю записи из базы данных, не совпадает с порядком, в котором я их помещаю. Это случается примерно 1 из каждых 4 раз, когда я пытаюсь его использовать, поэтому я не могу отладить его.

Редактировать Причина упорядочения здесь важна в том, что мы выгружаем таблицу в таблицу Excel, которая соответствует уже существующим там данным. Сортировка по может иметь некоторый прогресс, но есть столбец, который упорядочен по движению (то есть, 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

Ответы [ 2 ]

0 голосов
/ 20 января 2009

В Jet кластерный индекс (физический порядок) таблицы определяется ПЕРВИЧНЫМ КЛЮЧОМ или, в отсутствие PK, другим ключом, выбранным (случайным образом?) Механизмом. Однако физическое упорядочение происходит только при сжатии файла базы данных (.mdb, .mde, .accdb). Строки, вставленные после сжатия (или до первого сжатия), вставляются в порядке даты / времени. Теперь наименьшая временная гранула, поддерживаемая типом данных Jet DATETIME, составляет одну секунду, хотя под крышками значение хранится в виде двойного числа с плавающей запятой, поэтому мне интересно, недостаточно ли гранулярность для ваших целей. Но зачем полагаться на такие плохо документированные особенности пожилого двигателя ...?

Если вам известен порядок, в котором вы вставляете строки, то модель это в базе данных, например. используйте столбец INTEGER для хранения порядкового номера, для которого ваше приложение отвечает за предоставление значений. И, чтобы быть уверенным, на колонку также наложите УНИКАЛЬНОЕ ограничение. Затем просто ЗАкажите ваш столбец последовательности в запросах.

0 голосов
/ 17 января 2009

В вашем методе PopulateTmpTable () вы совершаете транзакцию, даже если произошла ошибка. Это то, что вы намеревались?

В ProcessNode () вы передаете объект команды, создаете новый, а затем используете переданный в?

...