题目:
现在数据库由于需要要自己定义唯一编号,唯一编号由3个数字组成。这三个数字我存储为nvarchar.
由于唯一编号在使用中不可能超过999条记录,所以3个足够用。但是碰到一个问题.第一次使用时添加记录可以001,002,003...这样顺序添加.
当对这些记录进行删除之后再次添加.要核对输入的记录是否重复。这样非常被动。
每次添加记录都要验证该编号是否存在。设计这样的数据库,实在是没辙.
现在有没有办法能够自己得出一个在999内的未使用的编号呢。
非常感谢。用存储过程亦可。我有想过遍历,但是效率不高。希望有更简洁的方式。再谢.http://community.csdn.net/Expert/topic/5152/5152276.xml?temp=.9417536

解决方案 »

  1.   

    先看看这个.记录编号缺号的处理编号 姓名
    1    张山
    3    历史
    4    王无
    6    李强
         桥三
         大兵我想对没有编号的进行编号的自动处理,但是已经有编号的不要进行修改。
    如果发现有断号的就将号码分配给没有编号的。
    结果如下:
    编号 姓名
    1   张山
    3   历史
    4   王无
    6   李强
    2   桥三
    5   大兵
    遍历记录,如果id为空,则找出最小未使用id,然后update找最小未使用id如下:
    select (case when exists (select 1 from test where id=1)
             then min(id+1) else 1 end)
    from test
    where id not in(select id-1 from test)
      

  2.   

    select top 999 identity(int,1,1) as id into autokey from sysobjects,sysobjects aalter table autokey add no varchar(3)
    GO
    update autokey
    set no = right('00'+cast(id as varchar),3)select * from 表 where 编号 not in (select no from autokey)
      

  3.   

    最后那名应该是
    select no from autokey where no not in (select distinct 编号 from 表)
      

  4.   

    --1、没有数据的情况
    if object_id('pubs..t') is not null
       drop table t
    gocreate table t(id char(3))select (case when exists (select 1 from t where cast(id as int)=1)
                 then right('00' + rtrim(cast(min(id + 1) as char(3))) , 3) else '001' end)
           as 最小数据
    from t
    where id not in(select id - 1 from t)drop table t--结果
    最小数据  
    ----- 
    001(所影响的行数为 1 行)
    --2、有数据且连号。
    if object_id('pubs..t') is not null
       drop table t
    gocreate table t(id char(3))insert into t(id) values('001')
    insert into t(id) values('002')
    insert into t(id) values('003')select (case when exists (select 1 from t where cast(id as int)=1)
                 then right('00' + rtrim(cast(min(id + 1) as char(3))) , 3) else '001' end)
           as 最小数据
    from t
    where id not in(select id - 1 from t)drop table t--结果
    最小数据  
    ----- 
    004(所影响的行数为 1 行)
    --3、有数据但断号
    if object_id('pubs..t') is not null
       drop table t
    gocreate table t(id char(3))insert into t(id) values('001')
    insert into t(id) values('002')
    insert into t(id) values('004')select (case when exists (select 1 from t where cast(id as int)=1)
                 then right('00' + rtrim(cast(min(id + 1) as char(3))) , 3) else '001' end)
           as 最小数据
    from t
    where id not in(select id - 1 from t)drop table t--结果
    最小数据  
    ----- 
    003(所影响的行数为 1 行)
      

  5.   

    select 1 from t where cast(id as int)=1
    怎样理解呢?这句
      

  6.   

    create table roy(id  char(3),name varchar(5))--定义一个函数
    create function roy_fun(@id char(3)=null)
    returns char(3)
    as
    begin
    declare @new char(3)
    (select @new=replicate('0',(3-len(max(cast(isnull(id,0) as int))+1)))
    +cast((max(cast(id as int))+1)as varchar) 
    from roy)
    return(@new)
    end
    --定义触发器
    create trigger roy_tr on roy
    for insert
    as
    update roy
    set id=isnull(dbo.roy_fun(null),'001')
    where id is null
    --测试
    insert into roy(name) values('a')select * from roy
    结果:
    id   name  
    ---- ----- 
    001  a
    002  a(所影响的行数为 2 行)
      

  7.   

    如果只是查询下一个值这样就行了
    select replicate('0',(3-len(max(cast(isnull(id,0) as int))+1)))
    +cast((max(cast(id as int))+1)as varchar) 
    from roy
      

  8.   

    --在增加一个值时存储更新 exec test
    create proc test
    as
    update roy
    id=replicate('0',(3-len(max(cast(isnull(id,0) as int))+1)))
    +cast((max(cast(id as int))+1)as varchar) 
    from roy where id is null
    --存储查询下一个值
    create proc test
    as 
    select replicate('0',(3-len(max(cast(isnull(id,0) as int))+1)))
    +cast((max(cast(id as int))+1)as varchar) 
    from roy
      

  9.   

    再来一贴
    create table test_ta(id  char(3),name varchar(10))
    --定义一个函数
    create function test_fun(@id char(3)=null)
    returns char(3)
    as
    begin
    declare @new char(3)
    (select @new=isnull(replicate('0',(3-len(max(cast(isnull(id,0) as int))+1)))
    +cast((max(cast(id as int))+1)as varchar),'001') 
    from test_ta)
    return(@new)
    end
    insert test_ta select dbo.test_fun(null),2--测试新增记录
    select *from test_ta--查看结果
    --定义触发器(用于批量新增记录)
    create trigger test_ta_tr on test_ta
    for insert
    as
    declare @i int
    set @i=0
    set nocount on
    update test_ta
    set id=replicate('0',3-len((select isnull(max(cast(id as int)),0) from test_ta)+@i))+
    cast((select isnull(max(cast(id as int)),0) from test_ta)+@i as varchar)
    ,@i=@i+1
    where id is null
    set nocount off
    --测试一次增加999记录
    --truncate table test_ta --清空表
    declare @i int,@j int
    select @i=1,@j=999
    while @i!>@j
    begin
    set nocount on
    insert test_ta(name) VALUES(@i)
    set nocount off
    select @i=@i+1
    end
    --触发器是更新id为空值的值
    --由于id有空值,isnull会有这样提示:警告: 聚合或其它 SET 操作消除了空值。
    select * from test_ta--查看结果--drop function test_fun--删函数
    --drop table test_ta--删测试表
      

  10.   

    1.根据需求是不是一定要999特殊编号,如果只是唯一性大可不必,将此字段定义主键和自增(种子)即可2.如果一定要实现其(999)中编号,包括唯一性和删除Key部分也要回收可以多种方式实现.
    1>加表方式(FreeKeyTable表),根据主表的所有可用的主键生成到FreeKeyTable表中.
      主表添加一个有效的就删除一个FreeKeyTable中的键(一定要有事务[它们是同一个事务])
    2>通过编程实现(一定要保证一个实现[单例])
      原理大同小异,所有的键操作都通过一个类来完成.
      初始化工作(生成有效键)
      获取有效键
      回收有效键根据以上功能可以这样定义接口
    public interface IFreeKeyManager
    {
        void Init();
        bool IsInit{get;}
        int getFreeKey();
        void Recycle(int key);
    }public class FreeKeyManager:IFreeKeyManager
    {
        protected IList keys=new ArrayList();
        protected bool isInit=false;    public bool IsInit{get{return isInit;}}
        public void Init()
        {
            //自己实现主键中没有用过的键添加到keys中
            isInit=true;
        }
        public int getFreeKey()
        {
            if(keys==null||keys.Count<=0)
                throw new Exception("键集合没有初始化或已经没有可用的键");
            int key=(int)keys[0];
            keys.Remove(0);
            return key;
        }
        //添加不成功或删除某键进行回收
        public void Recycle(int key)
        {
             keys.Add(key);
        }
    }当然这是简单的例子,还可以扩展存储方式.
    如:
    public interface IFreeKeyManager
    {
        void Init();
        bool IsInit{get;}
        int getFreeKey();
        Recycle(int key);
        SaveKeys();
    }
    将键值直接保存(文件,数据库或各种形式接下来写一个单例
    public class FreeKeyManagerFactory
    {
        static IFreeKeyManager keys=new FreeKeyManager();
        private FreeKeyManagerFactory();    public static IFreeKeyManager getInstance()
        {
             return keys;
        }
    }这样你可以轻松进行了使用了
    在系统加载的时候
    IFreeKeyManager keyManager FreeKeyManagerFactory.getInstance();
    if(!keyManager.IsInit)
        keyManager.Init();
    在添加时
    int key=FreeKeyManagerFactory.getInstance().getFreeKey();
    删除时
    FreeKeyManagerFactory.getInstance().Recycle(key);//删除的key
      

  11.   

    建一个表A, 填好000--999(Code)
    select top 1 code from A where not exists(select 1 from 表 B where A.code=b.code) order by A.Code