请教一个面试题目

lutaotony 2011-07-15 09:51:16
数据库中有这样一张表 订单号 客户编号 订单金额 三个字段
其中订单号字段为自动产生,格式如:YYYYMMDD0000(YYYYMMDD代表年,月,日,0000是流水号,流水号每天都从0001到9999自动生成)。为了满足以上要求,请你给出一种自动生成订单号的最优化方案(可以使用数据库的后台技术)。
...全文
190 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
lutaotony 2011-07-18
  • 打赏
  • 举报
回复
非常感谢大家的回复,分数不多,请大家见谅
lutaotony 2011-07-15
  • 打赏
  • 举报
回复
create trigger trordersale on ordersale
instead of insert
as
begin
insert into ordersale
select CONVERT(varchar(100), GETDATE(), 112)+
cast((10000-ROW_NUMBER() over(order by id)) as varchar(100)),customer,sale from inserted as tb
end
这是我写的,但是不知道应该怎样去用啊求教中
-晴天 2011-07-15
  • 打赏
  • 举报
回复
修正:
create table tb(订单号 varchar(14),客户编号 int,订单金额 int)
go
create trigger tri_dd
on tb
INSTEAD OF insert
as
begin
insert into tb
select convert(varchar(8),getdate(),112)+
right('0000'+ltrim((select count(*) from tb where left(订单号,8)=convert(varchar(8),getdate(),112))),4)订单号,
客户编号,订单金额 from inserted
end
go
insert into tb(客户编号,订单金额) select 12,5000
insert into tb(客户编号,订单金额) select 18,12000
go
select * from tb
/*
订单号 客户编号 订单金额
-------------- ----------- -----------
201107150000 12 5000
201107150001 18 12000

(2 行受影响)

*/
go
drop table tb
-晴天 2011-07-15
  • 打赏
  • 举报
回复
create table tb(订单号 varchar(14),客户编号 int,订单金额 int)
go
create trigger tri_dd
on tb
INSTEAD OF insert
as
begin
insert into tb
select convert(varchar(10),getdate(),112)+
right('0000'+ltrim((select count(*) from tb where left(订单号,10)=convert(varchar(10),getdate(),112))),4)订单号,
客户编号,订单金额 from inserted
end
go
insert into tb(客户编号,订单金额) select 12,5000
insert into tb(客户编号,订单金额) select 18,12000
go
select * from tb
/*
订单号 客户编号 订单金额
-------------- ----------- -----------
201107150000 12 5000
201107150000 18 12000

(2 行受影响)

*/
go
drop table tb
lutaotony 2011-07-15
  • 打赏
  • 举报
回复
是不是在插入数据的时候用触发器,然后
CONVERT(varchar(100), GETDATE(), 112)+cast((10000-ROW_NUMBER() over(order by getdate()
lutaotony 2011-07-15
  • 打赏
  • 举报
回复
求教,你这个是查询啊,不是很懂
Billy 2011-07-15
  • 打赏
  • 举报
回复
可以用触发器 instead of insert 然后修改其流水号,然后插入

<最优化方案> 观注中....
yubofighting 2011-07-15
  • 打赏
  • 举报
回复

select CONVERT(varchar(100), GETDATE(), 112)+cast((10000-ROW_NUMBER() over(order by getdate(), 客户编号)) as varchar(100)) as,客户编号,订单金额

from tb

yubofighting 2011-07-15
  • 打赏
  • 举报
回复
小乌,我欣赏你,不过被一户开挂灭了
yubofighting 2011-07-15
  • 打赏
  • 举报
回复

select CONVERT(varchar(100), GETDATE(), 112)+cast((10000-ROW_NUMBER() over(order by id)) as varchar(100)),客户编号,订单金额

from tb
cutebear2008 2011-07-15
  • 打赏
  • 举报
回复
用2个字段,感觉非常好啊,后台数据库管我怎么存呢,前端显示的时候是这样就ok了,^_^!
[Quote=引用 14 楼 happiness 的回复:]
1、row_number显然不合适,前面单号删除了就会产生重复
2、触发器显然不合适,性能消耗在这里不值得
3、小F的函数,看起来不错,但是可能只能用来玩玩,因为直接锁表太影响性能,并发稍高就会死翘翘

最优方法:
1、增加一表存放当前序号,表一个字段,只存放一行数据
2、增加各作业每天0点执行,把上述表数据改为0
3、写个存储过程取下一编号,时间部分用getdate(),编号部分取……
[/Quote]
mycodeis0000 2011-07-15
  • 打赏
  • 举报
回复
希望对有你帮助
mycodeis0000 2011-07-15
  • 打赏
  • 举报
回复

-------------步长表--------------
if exists(select 1 from sysobjects where id=object_id(N't_Step') and objectproperty(id,N'isUserTable')=1)
drop table t_Step
Go
create table t_Step
(
fnumber int,
fdatetime datetime
)
insert into t_Step values(0,getdate())

-----------------销售订单--------------------
if exists(select 1 from sysobjects where id=object_id(N't_SaleOrder') and objectproperty(id,N'IsUserTable')=1)
drop table t_SaleOrder
Go
create table t_SaleOrder
(
fid int identity(1,1),
订单号 varchar(20),
客户编号 varchar(20),
订单金额 money
)



-------------触发器--------------
if exists(select 1 from sysobjects where id=object_id(N'tri_insertSaleOrder') and objectproperty(id,N'IsTrigger')=1)
drop Trigger tri_insertSaleOrder
Go
create trigger tri_insertSaleOrder
on t_SaleOrder
for insert
as
--年月日
declare @FYear int
declare @FMonth int
declare @FDay int

declare @fnumber varchar(20)
--步长表中number
declare @maxNum int

--分别取出步长表中的年月日
select @maxNum=fnumber,@FYear=datepart(year,fdatetime),
@FMonth=datepart(month,fdatetime),@FDay=datepart(day,fdatetime) from t_Step
--步长计算是否到了第二天
if (datepart(year,getdate())*1000+datepart(month,getdate())*50+datepart(day,getdate()))>(@FYear*1000+@FMonth*50+@FDay)
begin
--步长计算如果到了第二天,清空NUMBER
update t_Step set fnumber=1,fdatetime=getdate()
set @maxNum=1
End
Else
Begin
set @maxNum=@maxNum+1
update t_Step set fnumber=@maxNum
End

--设置流水号格式
If len(convert(varchar(20),@maxNum))=1
Begin
set @fnumber='000'+convert(varchar(20),@maxNum)
End
Else if len(convert(varchar(20),@maxNum))=2
Begin
set @fnumber='00'+convert(varchar(20),@maxNum)
End
Else if len(convert(varchar(20),@maxNum))=3
Begin
set @fnumber='0'+convert(varchar(20),@maxNum)
End
set @fnumber=convert(varchar(20),getdate(),112)+@fnumber
update t_SaleOrder set 客户编号=@fnumber from t_SaleOrder t inner join inserted i on(t.fid=i.fid)



delete from t_SaleOrder
select * from t_SaleOrder
insert into t_SaleOrder values('C001','sssss',20000)
用除法器做

liang145 2011-07-15
  • 打赏
  • 举报
回复
樓上高人~~頂~~
Happiness 2011-07-15
  • 打赏
  • 举报
回复
代码就不写了,写这些没用的代码也是浪费时间
Happiness 2011-07-15
  • 打赏
  • 举报
回复
1、row_number显然不合适,前面单号删除了就会产生重复
2、触发器显然不合适,性能消耗在这里不值得
3、小F的函数,看起来不错,但是可能只能用来玩玩,因为直接锁表太影响性能,并发稍高就会死翘翘

最优方法:
1、增加一表存放当前序号,表一个字段,只存放一行数据
2、增加各作业每天0点执行,把上述表数据改为0
3、写个存储过程取下一编号,时间部分用getdate(),编号部分取上述表数据+1,取数据时锁表,+1数据写回表。

总之,这个编号有点浪费,不如用两个字段,一个日期,一个编号,就自动增长就可以
liang145 2011-07-15
  • 打赏
  • 举报
回复

create table tbA(订单号 nvarchar(20), 客户编号 nvarchar(10), 订单金额 int)

alter trigger SetID on tbA instead of insert
as
begin
declare @returnStr as int
set @returnStr=0
select @returnStr=max(cast(right(订单号,4) as int)) from tbA
where convert(varchar(8),getdate(),112)=Left(订单号,8)
if @returnStr is null
set @returnStr=0
;with CTE as (select convert(varchar(8),getdate(),112)+right('000'+ltrim(@returnStr+Row_number()over(order by getdate())),4) as 订单号 ,
客户编号,订单金额 from inserted)
insert tbA select * from CTE
end

insert tbA
select '111','c5',123 union all
select '111','c6',123 union all
select '111','c7',123 union all
select '111','c8',123

select * from tbA

订单号 客户编号 订单金额
-------------------- ---------- -----------
201107150001 c5 123
201107150002 c6 123
201107150003 c7 123
201107150004 c8 123

(4 row(s) affected)
sekai2011 2011-07-15
  • 打赏
  • 举报
回复

建议少用触发器,用小F的函数生成
yagebu1983 2011-07-15
  • 打赏
  • 举报
回复
用ROW_NUMBER这种方式会有问题存在!!
建议你写个函数!!通过此函数可以得到今天产生了多少单数,然后加1即可!!!
--小F-- 2011-07-15
  • 打赏
  • 举报
回复
--下面的代码生成长度为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
--*/

34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧