函数要里执行UPDATE语句,得到单据流水号,如何处理,其它方式有办法实现吗?

WuChenCan 2006-02-20 04:54:39
-- ==================================================
-- 名称:得到单据流水号
-- 实现功能:取得对应表的计数器,实现流水号功能.
-- 调用示例:SELECT F_LT_GetOrderNo(FId) as FID, * from Tab1 T1
left outer join T_OrderList T2 on T1.FTabID = T2.FID
-- ==================================================
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 FROM T_OrderList WHERE FID = @ID
-- 取得编号后,计数器加1
UPDATE T_OrderList SET FIncCount = FIncCount +1 -- 函数中不允许执行UPDATE,这种情况要怎么处理.
RETURNS @OrderNo

...全文
299 点赞 收藏 19
写回复
19 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
logoes 2006-03-20
邹健的示例

--下面的代码生成长度为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
--*/
回复
WuChenCan 2006-03-13
楼上的兄弟没明白我的意思,看来我只能另想他法了..
回复
hksl 2006-03-07
CREATE PROCEDURE n_GetBillNo
@billType char(2),--单据类型
@BillOutNo nvarchar(50) Output

AS

Begin

declare @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 Succeed

Failed:
RaisError(@ErrorMsg,16,1)
Rollback Tran
Set NoCount Off
Return 1

Succeed:
Commit Tran
Set NoCount Off
Return 0

End
GO
回复
logoes 2006-03-07
我也遇到同样问题,没办法,用了存储过程.因为不能直接用select,在只好另一个存储过程里用游标.
回复
logoes 2006-03-07
关注
回复
WuChenCan 2006-03-01
问题还没解决,请大家关注一下。谢谢了!
回复
WuChenCan 2006-02-21
流水号字段是表T_Order的物理字段
CREATE TABLE T_Order(
FID int IDENTITY (1, 1) NOT NULL,
FNumber varchar(40), -- 单据流水号
...
)
回复
WuChenCan 2006-02-21
设计数据库时没想用触发器,用触发器也存在一些问题,如果是软件客户端做的业务数据,用触发器流水号是在数据库生成的,那客户端保存后,还要再回数据库取一次数据.这样也不是很好.
不知还有其它好方法实现给运算后的结果集分配不同的流水号.
回复
子陌红尘 2006-02-21
流水号字段只是用于查询时显示,而并非表T_Order的物理字段?
回复
子陌红尘 2006-02-21
呵呵,为什么不用for insert触发器?
回复
WuChenCan 2006-02-21
子陌红尘大虾出招了,谢谢!
我把思路理一下:
-- 系统单据表,存放系统所以业务单据列表,存有生成流水号计数器
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 +1

UPDATE 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

不知我是否描述的清楚,分数虽然低,但可以再开贴送分.有点难度,请大家想想解决方法.在此谢过!
回复
子陌红尘 2006-02-21
流水号是在查询时生成的?
把表结构和需要输出的数据以及流水号规则说明一下,我觉得完全可以换个思路来实现。
回复
WuChenCan 2006-02-21
此问题有点难,请大虾们指点一二.谢谢!
回复
WuChenCan 2006-02-21
用存储过程也满足不了我的要求,因为我是想用函数与SELECT结合生成多个流水号.
如:
-- 分组单据信息,并给每组单据信息赋流水号.
select GetOrderNo(@OrderID) as 表流水号, FOrderInfo as 单据信息 from TabOrder group by FOrderInfo
回复
bugchen888 2006-02-20
--创建存储过程
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
回复
wgsasd311 2006-02-20
-- 要用存储过程,函数实现不了楼主要求
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
回复
Andy__Huang 2006-02-20
不要用到函數,那樣就麻煩了,按你的題意,應該這樣寫

update T1
set FIncCount=T2.FIncCount+1
from T_OrderList T1
left join T_OrderList T2
on T1.FTabID = T2.FID

要是樓主拿一些實例的數據來,那就更好說明 了

回复
WuChenCan 2006-02-20
楼上的兄弟没明白我的意思,如果这样子
SELECT @OrderNo = FIncCount + 1 FROM T_OrderList WHERE FID = @ID 操作并没有改变T_OrderList 表的FIncCount 的值,没有实现计数,那流水号就流不下去了.
回复
-狙击手- 2006-02-20
-- ==================================================
-- 名称:得到单据流水号
-- 实现功能:取得对应表的计数器,实现流水号功能.
-- 调用示例: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
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2006-02-20 04:54
社区公告
暂无公告