private string GET_GYS_GYSID(string province,int _ix)
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
string str = _ix.ToString().PadLeft(3, '0');//001
if (!gysbll.Exists(province + str))
{
return province + str;
}
else
{
_ix = _ix + 1;
str = _ix.ToString().PadLeft(3, '0');//001
return GET_GYS_GYSID(province,_ix);
}
}这个方法,我想的是判断这个字段是否存在,如果不存在直接输出,如果存在的话,数字加1然后输出,这个迭代总是出问题,该怎么处理
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
string str = _ix.ToString().PadLeft(3, '0');//001
if (!gysbll.Exists(province + str))
{
return province + str;
}
else
{
_ix = _ix + 1;
str = _ix.ToString().PadLeft(3, '0');//001
return GET_GYS_GYSID(province,_ix);
}
}这个方法,我想的是判断这个字段是否存在,如果不存在直接输出,如果存在的话,数字加1然后输出,这个迭代总是出问题,该怎么处理
所以你 12 行的注释就写错了 str = _ix.ToString().PadLeft(3, '0');//001 应是 002这样在递归调用 GET_GYS_GYSID(province,_ix) 时 _ix 总是有不同的值
不然,整个就陷入死循环了
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
string str = _ix.ToString().PadLeft(3, '0');//001
if (!gysbll.Exists(province + str))//你是要判断province的没存在?还是要判断province + str的存在?
{
return province + str;
}
else
{
_ix = _ix + 1;
//str = _ix.ToString().PadLeft(3, '0');//001 //这句没有意义
return GET_GYS_GYSID(province,_ix);
}
}你是要判断province的没存在?还是要判断province + str的存在?
既然你有 str = _ix.ToString().PadLeft(3, '0'),那么 _ix 就不会大于 999
如果到了就直接返回,而不进入递归
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
string str = _ix.ToString().PadLeft(3, '0');//001
if (!gysbll.Exists(province + str))//你是要判断province的没存在?还是要判断province + str的存在?
{
return province + str;
}
else
{
_ix = _ix + 1;
//str = _ix.ToString().PadLeft(3, '0');//001 //这句没有意义
return GET_GYS_GYSID(province,_ix);
}
}我们在数据库中的格式是AH001这样的,我要向数据库中插入AH001,AH002,AH003 这样的值
我首先定义一个数值AH001 判断数据库中是否存在,如果不存在就插入到数据库,如果存在我就加1得到AH002,如果AH002依然存在再加1,以此类推,应该怎么写
那么 AH999 存在的话,该返回什么呢? AH1000 吗?
显然超出了预期的长度,假定超长会被截断那么 AH1000 就变成了 AH100其实你只要查询出该列的最大值 max(字段) 就可以了,并不需要递归检查
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
string str = _ix.ToString().PadLeft(3, '0');//001
if (gysbll.Exists(province + str))
{
_ix = _ix + 1;
str = _ix.ToString().PadLeft(3, '0');//001
}
return province + str;
}
private string GET_GYS_GYSID(string province, int _ix)
{
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
return do_GET_SYS_GYSID(gysbll, province, _ix);
}
private string do_GET_GYS_GYSID(Oracle.BLL.GYS gysbll string province, int _ix)
{
if (_ix > 999)
{
throw new RuntimeException("blablabla");
}
string str = _ix.ToString().PadLeft(3, '0');//001
if (!gysbll.Exists(province + str))
{
return province + str;
} return do_GET_GYS_GYSID(gysbll, province, _ix + 1)
}
private string GET_GYS_GYSID(string province, int _ix)
{
if(_ix < 0 || _ix > 999)
{
// 不知你要如何处理
}
string fieldName = province + _ix.ToString().PadLeft(3, '0');
Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
if (gysbll.Exists(fieldName))
{
return GET_GYS_GYSID(province, _ix + 1);
}
return fieldName;
}
如,这句代码是使用已经存在的连接还是每次新连数连接?如果是新建连接,那么不论是你循环还是递归,都是会造成数据库连接池资源的耗尽!即算使用已经存在连接的连接,但是你本身的GYS对象也会大量堆积到堆中,造成内存的快速增长。递归与循环的不同之处在于,递归的实现是要保留现场的!所以在系统中的递归运算调用的深层是有限的(win7应该是63层),而循环却没有这个限制!循环多少次都可以的!这是递归的缺点所限制的。再说代码,代本身上是没大问题,就是多写了一句无用的语句或是代码运算上多了一点而已。/// 这是一个完整的递归方式!
private string GET_GYS_GYSID(Oracle.BLL.GYS gysbll, int _ix)
{
string str = (_ix%1000).ToString("AH000"); // 3.ToString("AH000")的运行结果是“AH003"
if (!gysbll.Exists(str)) return str; // 因为存在return,所以不必再写else,注意结果
return GET_GYS_GYSID(gysbll, _ix++); // 把gysbll作为参数输入时,防止递归中创建的大量GYS对象。
}
但是即使是这样,我们也无未能突破递归调用的限制,换句话来出,如果需要超出限制次数的查询,该方法会出现问题的。不用考虑什么死循环,本身递归层次就会引发exception!然后说一下数据库设计:
1,你查询的是不是主键?如果不是,在没有索引的情况下,查询速度比较慢。如果是,这么写入会引发聚集索引重排!数据量大一点麻烦会很大!
2,业务中是否有多线程?如果有,你查询完毕和在你插入时,两条线程交叉进行,必然会存在一个失败!单凭这两点的问题都能说明你系统设计存在极大缺陷!那么再进行优化的意义也不大了!如果不考虑以上两点,可以考虑给你优化建议:
1)批量查询,获得数据库中部分不存在的AH000编号。并做列表(队列也行)返回。
2)多线程加锁,每个线程随机获得一个AH000编号,并将编号从列表中删除(这个等于在缓存中干这个事)。
3)指定时间再次执行1)补充列表中的数据。2)步骤中某个线程可能未使用或者其他线程删除的用来回收。