书城计算机网络综合应用软件设计
8724600000021

第21章 数据分析、设计及实现(4)

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中备份与还原数据库的步骤。