5.3.3如何获得自动增长量
在表中设置自动增长量作为主键来唯一标识一条记录,例如上面例子中主表T_Order的列DetailID就是自动增长量。在SQL语句中,可以用@@IDENTITY获得插入一条数据后系统分配的自动增长量。例如:
INSERT T_Order(OrderDate,Vendor,TotalPrice)
Values(’2003—1—1’,’上海理工’,100)
select@@IDENTITY
5.3.4如何手动实现自增长的编码
使用系统的识别列(Identity)属性时,该列只能是整形,但是在很多情况下的表是有意义的,所以就要求手动实现主键自增长的功能。如果第一个类别为1001,第一个同层次的类别的编码就应该是1002,当要插入1001的子类别时,他的第一个自类别应该是10011001,第二个自类别应该是10011002,显然编码自身是有意义的,每个非根节点的编码的左边四位就是其父节点的编码。
可以用例5.1所示的函数实现按上面描述的规则自动生成ID的功能。当传入一个父类ID时,函数首先查找到该类别中的小类最大的编码,如果没有找到,说明该类别还没有小类,此时返回该类别中的小类的第一个编码,否则返回最大的编码加一之后的编码。
例5.1create FUNCTION dbo.fun_GenarateCategoryID(@id varchar(8))
RETURNS varchar(40)
AS
BEGIN
declare@max as varchar(40)
select@max=max(Categoryid) from category
where ParentCategoryID=@id
if@max is null
if@id=’0’
set@max=’1001’
else
begin
set@max=@id+’1001’
end
else
begin
set@max=cast(@max as bigint)+1
end
return@max
END
例5.2
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’0’),’服装’,’服装大类’,’0’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’1001’),’西服’,’西服小类’,’1001’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)values(dbo.fun_GenarateCategoryID(’1001’),’夹克’,’夹克小类’,’1001’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’1001’),’毛衣’,’毛衣小类’,’1001’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’10011003’),’全羊毛衣’,’毛衣的更小的类别,’10011003’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’10011003’),’50%羊毛衣’,’毛衣的更小的类别’,’10011003’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’0’),’农业’,’农业大类’,’0’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’1002’),’粮食’,’粮食小类’,’1002’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’1002’),’饲料’,’饲料小类’,’1002’)
go
insert category(CategoryID,CategoryName,Remark,ParentCategoryID)
values(dbo.fun_GenarateCategoryID(’0’),’食品’,’食品大类’,’0’)
go
使用例5.2的脚本插入数据,得到结果,显然所有的编码按照我们自定义的规则在自动增长。
5.3.5如何实现出入库类型的表
为了保持数据的一致性,在插入进货表和出库表的时候,同时要修改货物表中的库存。这里用触发器来实现。
进货触发器:在插入进货表的时候,自动更新货物库存。
CREATE TRIGGER Tri_InStore ON dbo.T_InStore
FOR insert
as
begin tran
declare@Num int
select@Num=InStoreNum
from inserted
update T_Product
set ProductStoreNum=ProductStoreNum+@Num
where ProductID in
(select ProductID from inserted)
if@@error>;0
rollback tran
else
commit tran
出货触发器:在插入出货表的时候,首先判断出货数量是否大于库存量,如果小于库存量,自动更新货物库存。
CREATE TRIGGER Tri_OutStore ON dbo.T_OutStore
FOR insert
as
begin tran
declare@StoreNum int
declare@Num int
select@StoreNum=ProductStoreNum
From T_Product
Where T_Product.ProductID in
(select ProductID from inserted)
select@Num=OutStoreNum
from inserted
if@StoreNum<;@Num
rollback tran
update T_Product
set ProductStoreNum=ProductStoreNum@Num
where ProductID in
(select ProductID from inserted)
if@@error>;0
rollback tran
else
commit tran
以上完成的触发器都是针对一条记录的插入操作来实现的。如果进行批量录入,则需要使用游标,循环读出插入值,每读出一条记录值,便更新相应库存数量。
5.3.6如何查询快要过期的产品
在数据库的查询中,对于时间的操作非常普遍,经常会碰到日期的处理和计算问题。下面主要介绍DATEDIFF函数的操作,DATEDIFF函数返回跨两个指定日期的日期和时间边界数。举个例子,计算并返回2008—1—1至2008—12—26之间有几个星期,这里我们就要用到DATEDIFF函数,语句如下所示:
select DATEDIFF(week,’2008—1—1’,’2008—12—26’)as weeknum
DATEDIFF的语法为DATEDIFF(datepart,startdate,enddate)
其中startdate和enddate分别为起始日期和结束日期,datepart是规定在日期的哪一部分计算差额的参数。Datepart参数可以取年、月、星期、日、小时等。
5.3.7如何查询各门课的第一名的成绩
在查询中经常会遇到类似的问题,查询操作首先要将各门课的成绩分组,然后在各个组中找到最高分。这里主要结束分组操作:Groupby。
Groupby用于select语句中,指定用来放置输出行的组,指定Groupby时,选择列表中任一非聚合表达式内的所有列都应包含在Groupby列表中,或者Groupby表达式必须与选择列表表达式完全匹配。下面是查询各门课的第一名的成绩的SQL语句:
Select course,max(mark)
From T_courses
Group by course
5.3.8如何将SQL上的数据导出并还原到另一台机器数据库的备份操作步骤如下:
①选中需要备份的数据库。
②单击右键,选择【所有任务】,单击【备份数据库】。
③在【常规】选项卡中选择备份类型,可以选择【完全备份】。
④单击【目的】中的【添加】,为数据库选择备份的目的地。
⑤在【重写】单选框中,用户选择【追加到媒体】,那么数据库备份将从文件的最后一行开始。如果用户选择【重写现有媒体】,那么将会覆盖文件中的原有内容。
数据库的还原操作步骤如下。
①首先,在SQL Server中建立一个和目标数据库同名的空数据库。
②选中数据库,单击右键,选择【所有任务】,单击【还原数据库】。
③在【常规】选项卡中,选择【还原】中的【从设备】。
④在【参数】中单击【选择设备】。
⑤在【选择还原设备】中,单击【还原自】中的【添加】。
⑥在【选择还原目的】中,选中【文件名】,单击右边的按钮,来选择还原文件。
思考题
1.逻辑设计的目的是什么?
2.设某商业集团数据库中有三个实体集:一是“商店”实体集,属性有商店编号、商店名、地址等;二是“商店”实体集,属性有商品号、商品名、规格、单价;三是“职工”实体集,属性有职工编号、姓名、性别、业绩等。商店与商品间存在“销售”联系,每个商店可销售多种商品,每种商品也可放在多个商店销售,每个商店销售每一种商品,有月销售量;商店与职工间存在着“聘用”联系,每个商店有许多职工,每个职工只能在一个商店工作,商店聘用职工有聘期和月薪。试画出ER图,并在图上注明属性、联系的类型。再转换成关系模式集,并指出每个关系模式的主键和外键。
3.数据库的实现需要完成哪些工作?
4.简述SQL Server2000中备份与还原数据库的步骤。