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然后输出,这个迭代总是出问题,该怎么处理

解决方案 »

  1.   

    11 行有 _ix = _ix + 1;
    所以你 12 行的注释就写错了 str = _ix.ToString().PadLeft(3, '0');//001 应是 002这样在递归调用 GET_GYS_GYSID(province,_ix) 时 _ix 总是有不同的值
    不然,整个就陷入死循环了
      

  2.   

     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))//你是要判断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的存在?
      

  3.   

    给 _ix 一个上限
    既然你有 str = _ix.ToString().PadLeft(3, '0'),那么 _ix 就不会大于 999
    如果到了就直接返回,而不进入递归
      

  4.   

    感谢,我再解释一下 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))//你是要判断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,以此类推,应该怎么写
      

  5.   

    你写的并没有太大问题,只是 若 AH998 存在,会返回 AH999
    那么 AH999 存在的话,该返回什么呢? AH1000 吗?
    显然超出了预期的长度,假定超长会被截断那么 AH1000 就变成了 AH100其实你只要查询出该列的最大值 max(字段) 就可以了,并不需要递归检查
      

  6.   

    不需要递归,直接用sql截取数值部分查最大值,select max(substr(字段, 开始位置, 长度)) from my_table试试看,手头没有oracle,未测试
      

  7.   

     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))
                {
                    _ix = _ix + 1;
                    str = _ix.ToString().PadLeft(3, '0');//001
                }
            return province + str;
            }
      

  8.   

    IOS越狱工具:absinthewin2.0.2下载
      

  9.   

    觉得有两个问题。1) 如果_ix对应的记录不存在,递归会一直进行,直到栈空间耗尽。2) 每次递归都建立GSY对象,造成CPU和内存使用上的浪费。不如改成
    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)
    }
      

  10.   


            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;
            }
      

  11.   

    从本身这段代码上来看,在业务设计存在很大的问题。先说一下自身代码上的问题,确实如22楼所说,递归时可能存在数据库连接层上的浪费,第二是递归本身的资源浪费。Oracle.BLL.GYS gysbll = new Oracle.BLL.GYS();
    如,这句代码是使用已经存在的连接还是每次新连数连接?如果是新建连接,那么不论是你循环还是递归,都是会造成数据库连接池资源的耗尽!即算使用已经存在连接的连接,但是你本身的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)步骤中某个线程可能未使用或者其他线程删除的用来回收。