1.
select 'A'+right(convert(varchar,10000+convert(int,right(max(num),4))+1),4) from T
2.
declare @tmp int
select @tmp=convert(int,right(max(num),4))+1 from T
set @tmp=convert(int,@tmp+rand()*(9999-@tmp))
select 'A'+right(convert(varchar,@tmp),4)

解决方案 »

  1.   

    --可以解决第一个问题if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[t1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [dbo].[t1]
    GOCREATE TABLE [dbo].[t1] (
    [id] [int] IDENTITY (1, 1) NOT NULL ,
    [c1] [varchar] (50) COLLATE Chinese_PRC_CI_AS NULL ,
    [c2] AS (replace(('A' + convert(char(5),(10000 + [id]))),'A1','A')) 
    ) ON [PRIMARY]
    GOinsert t1select 'a'
    union all
    select 'b'
    union all
    select 'c'
    union all
    select 'a'
    union all
    select 'b'
    union all
    select 'c'
    union all
    select 'a'
    union all
    select 'b'
    union all
    select 'c'
    union all
    select 'a'
    union all
    select 'b'
    union all
    select 'c'select * from t1drop table t1/*1 a A0001
    2 b A0002
    3 c A0003
    4 a A0004
    5 b A0005
    6 c A0006
    7 a A0007
    8 b A0008
    9 c A0009
    10 a A0010
    11 b A0011
    12 c A0012*/
      

  2.   

    jixiaojie:
    不行吧, 你加了一个虚拟列,那只是一个依附在ID列的计算列。
    没有ID列就没有c2列。
      

  3.   

    filebat(Mark):
    呵呵,你说的对,计算列依赖id列,也不能编辑,只是突然想到的一个想法实现类似搂主想要的自增效果,老大不要见笑,刚刚出道,多多指教^_^。
      

  4.   

    如果你非要这么做,最好给你的表加个自动编号
    create table Test(tid int identity(1,1),num char(5),col(varchar(6))CREATE TRIGGER tg_Test ON Test
    FOR INSERT
    AS
    DECLARE
    @Tid int,
    @num char(5)
    select @Tid=tid from inserted
    set @num='A'+right('0000'+cast(@Tid as varchar(5)),4)
    update Test set num=@num where tid=@Tid
      

  5.   

    select IDENTITY(int,1,1) AS spid, * into #T1 from table1select 'A'+ right('0000000000'+convert(varchar(10),spid),4)  as spid,
    *  from #T1
      

  6.   

    /*触发器中实现自动编号的方法是:找出当前最大编号,再将其加1(已经考虑过行集触发的情况, 即可以处理 insert ... select ...等)
    但是这种方法的可能会出现断层(类似分块内存管理中会出现碎片)。比如说:用户删除了中间的某条记录,则该记录的编号,在以后不能被用上了。
    解决的方法有两个:当update或delete时,自动将后面的序号移到前面来。第二种方法是再insert时,扫描原表找出第一个空出的来的序号,再利用该序号来进行编号(这种方法效率不高,而且较复杂)
    */
    if object_id('ta') is not null drop table ta
    go
    create table ta(strId char(5), value int)--strID为序列号, value为存放的数据
    insert ta  select 'A0001', 2
    union  all select 'A0002', 3
    union  all select 'A0002', 3
    union  all select 'A0003', 3
    union  all select 'A0003', 3
    union  all select 'A0004', 3
    --创建触发器
    if object_id('tr_ta') is not null drop trigger tr_ta
    go
    create trigger tr_ta
    on ta
    after insert, update
    as
     if (exists(select 1 from ( select strId, times=count(*) from ta  where strId is not null group by strId)t
          where t.times<>1))
        begin 
      select * , '1' from ta
            rollback tran
        raiserror('操作失败:不能插入重复列', 16, 1)
            return
        end
     if not exists(select 1 from deleted) --表示为插入
        if exists(select 1 from inserted where strId is null)--插入记录中有strID为空的情况
        begin --找出strID的最大值, 再将最大值加一。
    --这种方法可能出现序号中有空出的情况(原记录被deleted了),但是已经不能插入了。
    --此时可以用类似存储空间的分区管理的方法来解决
        declare @id int, @strid varchar(4)
        select @id=convert(int, stuff(max(strId), 1, 1, ''))   from ta    update ta
        set @id=@id+1, @strId=convert(varchar(4), @id), 
    strId='A'+stuff(@strId, 1, 0, replicate('0', 4-len(@strId)))
        where strId is null    
        end
    go
    --测试用例1
    begin tran
    select* from ta
    insert ta(value) select 4
    union all select 7
    union all select 8
    select* from ta
    rollback tran
    --测试用例2(此时修改的strId已经存在, 所以会出错)
    begin tran
    select* from ta
    delete ta where strId like '%003'
    update ta set strId='A0002' where strId like '%001'
    select* from ta
    rollback tran