三颗纽扣

世界上最宽广的是海洋,比海洋更宽广的是天空,比天空更宽广的是人的胸怀

导航

iBatis update statement SQL 语句的Bug以及解决办法

iBatis 中可以使用 <generate> 标签自动生成简单的 CRUD SQL 语句,可以节约很多SQL语句的编写工作。但是这个特性有一个小Bug,自动生成的 UPDATE 语句可能存在语法错误。查看一下源代码,发现这确实是 iBatis 的Bug,不过可以通过一个简单的方法避过这个 BUG。
以下是 IBatisNet.DataMapper.Configuration.Statements BuildUpdateQuery 方法的代码片段。
 1    StringBuilder builder = new StringBuilder();
 2    Update update = (Update) statement;
 3    int count = statement.ParameterMap.PropertiesList.Count;
 4    string[] strArray = update.Generate.By.Split(new char[] ',' });
 5    builder.Append("UPDATE ");
 6    builder.Append("\t" + update.Generate.Table + " ");
 7    builder.Append("SET ");
 8    for (int i = 0; i < count; i++)
 9    {
10        ParameterProperty property = statement.ParameterMap.PropertiesList[i];
11        if (update.Generate.By.IndexOf(property.ColumnName) < 0)
12        {
13            if (i < ((count - strArray.Length) - 1))
14            {
15                builder.Append("\t" + property.ColumnName + " = ?,");
16            }

17            else
18            {
19                builder.Append("\t" + property.ColumnName + " = ? ");
20            }

21        }

22    }

23    builder.Append(" WHERE ");
24

strArray 中保存了那些选择用作 Key 的字段名,因此,后面用判断 if (i < ((count - strArray.Length) - 1)) 来确定是否要在生成的 SET xxx = xxx 后添加逗号。但是,请注意,这个 if 语句的逻辑是错误的,这将导致后面 n(n取决于选择做为Key的字段的数量)个 SET 部分被错误的少添加了逗号。绕过这个BUG的方法很简单,就是将用作Key的那些字段放到 ParameterMap的最后进行声明,这样,少添加的逗号后正好是那些Key字段,也就正好得到了正确的结果。
正确修改的代码,应该是这个样子的(突出显示部分):

 1    StringBuilder builder = new StringBuilder();
 2    Update update = (Update) statement;
 3    int count = statement.ParameterMap.PropertiesList.Count;
 4    string[] strArray = update.Generate.By.Split(new char[] ',' });
 5    builder.Append("UPDATE ");
 6    builder.Append("\t" + update.Generate.Table + " ");
 7    builder.Append("SET ");
 8    for (int i = 0, fldCount = 0; i < count; i++)
 9    {
10        ParameterProperty property = statement.ParameterMap.PropertiesList[i];
11        if (update.Generate.By.IndexOf(property.ColumnName) < 0)
12        {
13            if (fldCount < ((count - strArray.Length) - 1))
14            {
15                builder.Append("\t" + property.ColumnName + " = ?,");
16            }

17            else
18            {
19                builder.Append("\t" + property.ColumnName + " = ? ");
20            }

22            fldCount ++;
23        }

24    }

25    builder.Append(" WHERE ");
26

posted on 2008-06-12 21:58  三颗纽扣  阅读(1430)  评论(0编辑  收藏  举报