-- ==================================================
-- 名称:得到单据流水号
-- 实现功能:取得对应表的计数器,实现流水号功能.
-- 调用示例:SELECT F_LT_GetOrderNo(FId) as FID, * from Tab1 -- ==================================================
CREATE TABLE T_OrderList(
FID int IDENTITY (1, 1) NOT NULL,
FIncCount int -- 计数器
)CREATE FUNCTION F_LT_GetOrderNo(@ID int)
AS RETURN VARCHAR(32)
DECLARE @OrderNo int
SELECT @OrderNo = FIncCount  + 1  FROM T_OrderList WHERE FID = @ID
    -- 取得编号后,计数器加1

RETURNS @OrderNo

解决方案 »

  1.   

    楼上的兄弟没明白我的意思,如果这样子
    SELECT @OrderNo = FIncCount  + 1  FROM T_OrderList WHERE FID = @ID 操作并没有改变T_OrderList 表的FIncCount 的值,没有实现计数,那流水号就流不下去了.
      

  2.   

    不要用到函數,那樣就麻煩了,按你的題意,應該這樣寫update T1
    set FIncCount=T2.FIncCount+1
    from T_OrderList  T1
    left join T_OrderList T2
    on T1.FTabID = T2.FID要是樓主拿一些實例的數據來,那就更好說明 了
      

  3.   

    -- 要用存储过程,函数实现不了楼主要求
    create proc p (@ID int,@orderno int output)
    as
    DECLARE @OrderNo int
    SELECT @OrderNo = FIncCount FROM T_OrderList WHERE FID = @ID
        -- 取得编号后,计数器加1
    if @orderno is not null
    UPDATE T_OrderList SET FIncCount = FIncCount +1 -- 函数中不允许执行UPDATE,这种情况要怎么处理.

    go
    --调用
    declare @orderno int
    exec p 3,@orderno output
    select @orderno
      

  4.   

    --创建存储过程
    CREATE PROC dbo.GetOrderNo(@FID INT)
    AS
    UPDATE T_OrderList SET FIncCount = FIncCount +1 WHERE FID=@FID
    SELECT FIncCount FROM T_OrderList WHERE FID=@FID--调用存储过程
    EXEC GetOrderNo @FID=45
      

  5.   

    用存储过程也满足不了我的要求,因为我是想用函数与SELECT结合生成多个流水号.
    如:
    -- 分组单据信息,并给每组单据信息赋流水号.
    select GetOrderNo(@OrderID) as 表流水号, FOrderInfo as 单据信息 from TabOrder group by FOrderInfo
      

  6.   

    子陌红尘大虾出招了,谢谢!
    我把思路理一下:
    -- 系统单据表,存放系统所以业务单据列表,存有生成流水号计数器
    CREATE  TABLE  T_OrderList(  
               FID  int  IDENTITY  (1,  1)  NOT  NULL,  
               FIncCount  int  --  计数器  
               FOrder varchar(30) not Null
               )  -- 系统业务单据,存放企业日常业务数据,具体每单有一个单据流水号
    CREATE  TABLE  T_Order(  
               FID  int  IDENTITY  (1,  1)  NOT  NULL,  
               FNumber varchar(40),  -- 单据流水号  
               FOrderInfo varchar(30)
               )  -- 现系统要求自动运算,将运算后的数据填充到T_Order业务表中.填充时各记录要生成不同的单据流水号.我原先的实现想法是用存储过程:
    CREATE    PROCEDURE P_OnlyC
      @CodeC VARCHAR(48) OUTPUT
    AS
    DECLARE @OnlyC VARCHAR(48)
    ,@FIncCount INTEGER-- 取出当前单据流水号
    SELECT @FIncCount=FIncCount FROM T_OrderList WHERE FID=@CodeC
    -- 流水号加1
    SELECT @FIncCount = @FIncCount +1UPDATE T_OrderList SET FIncCount = @FIncCount WHERE FID= @CodeC-- 组织各个编码
    SELECT @OnlyC = @CodeC  + '-' + @OnlyC
    SELECT @CodeC = @OnlyC; SELECT @OnlyC AS FNumber
    -- print @CodeC
    GO但这程方法不能在SELECT语句运算出的结果中调用.如前面写的SELECT P_OnlyC(FId)  as  流水号,  *  from (select sum(..) from tab..) Tab1  所以我想用函数,但函数里又没办法执行递增流水号:CREATE  FUNCTION  F_LT_GetOrderNo(@ID  int)  
    AS  RETURN  VARCHAR(32)  
               DECLARE  @OrderNo  int  
               SELECT  @OrderNo  =  FIncCount  FROM  T_OrderList  WHERE  FID  =  @ID  
           --  取得编号后,计数器加1  
               UPDATE  T_OrderList  SET  FIncCount  =  FIncCount  +1  --  函数中不允许执行UPDATE  
               RETURNS  @OrderNo  不知我是否描述的清楚,分数虽然低,但可以再开贴送分.有点难度,请大家想想解决方法.在此谢过!
      

  7.   

    呵呵,为什么不用for insert触发器?
      

  8.   

    流水号字段只是用于查询时显示,而并非表T_Order的物理字段?
      

  9.   

    流水号字段是表T_Order的物理字段
    CREATE  TABLE  T_Order(  
               FID  int  IDENTITY  (1,  1)  NOT  NULL,  
               FNumber varchar(40),  -- 单据流水号  
               ...
               )
      

  10.   

    我也遇到同样问题,没办法,用了存储过程.因为不能直接用select,在只好另一个存储过程里用游标.
      

  11.   

    CREATE PROCEDURE n_GetBillNo 
    @billType  char(2),--单据类型
    @BillOutNo  nvarchar(50) Output ASBegindeclare @NowNO int
    declare @date char(10)
    declare @Symbol nvarchar(10)
    declare @ErrorMsg nvarchar(200)Set NoCount On
    Begin Tran
    --设定延时
    SET LOCK_TIMEOUT 5000--取当前序号
    Select @NowNO=fnumber,@Symbol=fCode,@date=Convert(char(8),fDate,112) from n_BillNo  With(xLock) where fcode=@BillType
    if @@Error<>0
       begin
       Set @ErrorMsg='数据被锁定,请求超时!'
       Goto Failed
       end
    --是否是新的一月
    if Convert(char(8),getdate(),112)<>@date
    Set @NowNo=1
    else
    Set @NowNo=@NowNo+1--更新当前序列号和设置最后更新日期
    update n_BillNo set fNumber=@NowNO,fDate=GetDate() where fcode=@BillType
    if @@Error<>0
       begin
       Set @ErrorMsg='更新外部序列号失败!'
       Goto Failed
       end--取得单号
    Set @BillOutNo=lTrim(@SymBol)+Convert(char(8),GetDate(),112)+Right(('0000'+Convert(varchar,@NowNO)),4)Goto SucceedFailed:
      RaisError(@ErrorMsg,16,1)
      Rollback Tran  
      Set NoCount Off
      Return 1Succeed:
      Commit Tran
      Set NoCount Off
      Return 0End
    GO
      

  12.   

    邹健的示例--下面的代码生成长度为8的编号,编号以BH开头,其余6位为流水号。
    --得到新编号的函数
    CREATE FUNCTION f_NextBH()
    RETURNS char(8)
    AS
    BEGIN
    RETURN(SELECT 'BH'+RIGHT(1000001+ISNULL(RIGHT(MAX(BH),6),0),6) FROM tb WITH(XLOCK,PAGLOCK))
    END
    GO--在表中应用函数
    CREATE TABLE tb(
    BH char(8) PRIMARY KEY DEFAULT dbo.f_NextBH(),
    col int)--插入资料
    BEGIN TRAN
    INSERT tb(col) VALUES(1)
    INSERT tb(col) VALUES(2)
    INSERT tb(col) VALUES(3)
    DELETE tb WHERE col=3
    INSERT tb(col) VALUES(4)
    INSERT tb(BH,col) VALUES(dbo.f_NextBH(),14)
    COMMIT TRAN--显示结果
    SELECT * FROM tb
    /*--结果
    BH         col 
    ---------------- ----------- 
    BH000001  1
    BH000002  2
    BH000003  4
    BH000004  14
    --*/