今天運行單元測試的時候,有一段突然出現問題,測試代碼大致如下:
1 [Test]
2 public void TestSelectSql()
3 {
4 try
5 {
6 //建立暫存資料表
7 DBFactorySingleton.GetInstance().ExecuteSql("create table testSql (id int,name varchar(20)) ");
8 }
9 catch(Exception)
10 {
11 //刪除臨時資料
12 DBFactorySingleton.GetInstance().ExecuteSql("drop table testSql ");
13 //建立暫存資料表
14 DBFactorySingleton.GetInstance().ExecuteSql("create table testSql (id int,name varchar(20)) ");
15
16 }
17
18 //插入資料
19 DBFactorySingleton.GetInstance().ExecuteSql("insert into testSql values(1,'10')");
20 DBFactorySingleton.GetInstance().ExecuteSql("insert into testSql values(2,'20')");
21
22 string selectSql="select * from testSql";
23 //查詢資料
24 IDataReader read= DBFactorySingleton.GetInstance().SelectSql(selectSql);
25 Assert.IsNotNull(read);
26
27 read.Read();
28 Assert.AreEqual( read[0].ToString(),"1");
29 Assert.AreEqual( read[1].ToString(),"10");
30
31 read.Read();
32 Assert.AreEqual( read[0].ToString(),"2");
33 Assert.AreEqual( read[1].ToString(),"20");
34
35 Assert.IsFalse( read.Read()); //只有兩條記錄
36 read.Close();
37 //添加一列
38 DBFactorySingleton.GetInstance().ExecuteSql("alter table testSql add testcolumn int");
39
40
41 //查詢資料
42 read= DBFactorySingleton.GetInstance().SelectSql(selectSql);
43 Assert.IsNotNull(read);
44
45
46 read.Read();
47 Assert.AreEqual(3,read.FieldCount) ;
48
49 read.Close();
50//刪除臨時資料
51 DBFactorySingleton.GetInstance().ExecuteSql("drop table testSql ");
52 }
問題出現在第47行,即先執行某查詢,然後添加欄位,重新查詢出來的結果中 欄位數量不變!
這個unit在Sqlserver中測試是沒有問題的,為什麼在Oracle中就不行了呢?
開始的時候,以為Oracel的Connection緩衝的原因,於是在ODP.net的連接字串中加入Pooling=false,不使用串連池,但測試還是不通過。
即然與串連池無關,那就可能是查詢本身的問題,突然想到原來在做Oracle最佳化時候的一個原則:盡量執行同樣的SQL語句。 是否與這有關呢?
在第40行加入:
selectSql="select * from testSql "; //後面加一空格
再次運行,測試通過!
總結:在Oracle中,同樣的Sql語句在查詢的時候效能會更高,但如果修改了表結構,查詢結果中的表格保持不變。