ACCESS插入数据得到自增ID的问题

 

今天碰到一个很奇怪的问题。

在C#写的WINFORM程序里面连接ACCESS数据库,插入数据库取最大ID.代码如下:

   1:              String strSql = String.Format("INSERT INTO TABLE1 VALUES ()");
   2:              while (OleDB.ExecuteNonQuery(Program.OfflineDBConnectionString, strSql) != 1)
   3:              {
   4:                  if (MessageBox.Show("保存失败!是否重试?", "提示", MessageBoxButtons.RetryCancel, MessageBoxIcon.Question) != DialogResult.Retry)
   5:                      return 0;
   6:              }
   7:              strSql = "SELECT MAX([ID]) AS MAXID FROM TB_BIAOZHU";
   8:              object oid = OleDB.ExecuteScalar(Program.OfflineDBConnectionString, strSql);
   9:              int iMaxId = 0;
  10:              if (oid != DBNull.Value)
  11:                  iMaxId = int.Parse(oid.ToString());
  12:              return iMaxId;

 

注:OleDb是自己封闭的一个操作ACCESS的类。

当表是空的时候,如果直接运行,那么第8行会查询出一个空值出来,于是返回0 。但很明显,前面的INSERT是会执行成功才会执行到这里来,如果用单步运行模式,那么会一切正常的运行成功。这真的是很奇怪的事情。

在第8行之前加入一句休眠1S的语句后,一切就正常了。但是很疑惑为什么会这样,明明已经插入成功了,为什么查询不出最大的ID来呢?难道是用的ACCESS数据库版本或者JETDB引擎的版本有问题?最后没有办法,只好在第8句运行返回DBNULL的时候休眠1秒后重新运行查询语句来解决。如下:

   8:              object oid = OleDB.ExecuteScalar(Program.OfflineDBConnectionString, strSql);
   9:              if (oid == DBNull.Value)
  10:              {
  11:                  System.Threading.Thread.Sleep(1000);
  12:                  oid = OleDB.ExecuteScalar(Program.OfflineDBConnectionString, strSql);
  13:              }

虽然问题用很不爽的方式解决了,但还是希望弄明白为什么。

二○○九年六月二十六日 23时40分:最新进展.总算弄明白为什么了。原来我原先的语句是分两次执行SQL语句。也就是分别对数据库建立了一次连接。

当我把两个语句(INSERT和SELECT)放在一个连接里执行之后,一切就正常了。

因为ACCESS不支持多条语句放在一起执行,必须在代码里面依次执行。所以只好自己又写了一个方法,传入一个SQL语句的数组,然后遍历每个元素放在同一个OleDbCommand里面执行。代码如下:

   1:   
   2:          /// <summary>
   3:          /// 实际类似于存储过程的方案。依次执行数组中的语句。最后一条语句使用ExecuteScalar返回值。
   4:          /// </summary>
   5:          /// <param name="strConnectionString"></param>
   6:          /// <param name="strSqls"></param>
   7:          /// <returns></returns>
   8:          public static object ExecuteScalar(String strConnectionString, String[] strSqls)
   9:          {
  10:              OleDbConnection Oleconn = new OleDbConnection(strConnectionString);
  11:              OleDbCommand cmd = new OleDbCommand();
  12:              cmd.Connection = Oleconn;
  13:              try
  14:              {
  15:                  Oleconn.Open();
  16:                  int i = 0;
  17:                  foreach (String strSql in strSqls)
  18:                  {
  19:                      cmd.CommandText = strSql;
  20:                      if (i < strSqls.Length - 1)
  21:                          cmd.ExecuteNonQuery();
  22:                      else
  23:                      {
  24:                          return cmd.ExecuteScalar();
  25:                      }
  26:                      i++;
  27:                  }
  28:                  //永远不会执行到的语句。
  29:                  return null;
  30:              }
  31:              catch
  32:              {
  33:                  return null;
  34:              }
  35:              finally
  36:              {
  37:                  if (Oleconn.State == ConnectionState.Open)
  38:                      Oleconn.Close();
  39:              }
  40:          }
posted @ 2009-06-26 22:25  绝殇  阅读(5995)  评论(2编辑  收藏  举报