数据库实验报告

 

 

 

 

 

 

 

数据库原理与技术实验报告

 

课程名称:数据库原理与技术

 

实验报告要求

1.         列出所有的SQL语句和源代码;

2.         程序要求有适当的注释;

3.         对数据完整性约束实施、实验三、实验四和实验五要求给出相应的测试用例。

4.         实验报告提交电子档。

 

实验内容

 

实验一:创建表、更新表和实施数据完整性

 

1.  运行给定的SQL Script,建立数据库GlobalToyz

2.  在企业管理器中建立所有表的关系图。

3.  利用系统定义的存储过程sp_helpdb查看数据库的相关信息,例如所有者、大小、创建日期等。

4.  列出所有表中出现的约束(包括Primary key, Foreign key, check constraint, default, uniqueexec sp_helpconstraint Category

如此类推

5. Recipient表和Country表中的cCountryId属性定义一个用户自定义数据类型,并将该属性的类型定义为这个自定义数据类型。

   exec sp_addtype hqok,'char(3)','null'

   然后在企业管理器中打开该表,并对该类型进行重定义

6.  把价格在$20以上的所有玩具的信息拷贝到称为PremiumToys的新表中。

   create table PremiumToys

(

       cToyId           char(6)  check(cToyId like('[0-9][0-9][0-9][0-9][0-9][0-9]') )

                            constraint tt_id primary key clustered,

                           

       vToyName      varchar(20) not null,

       vToyDescription     varchar(250),

       cCategoryId    char(3) references Category(cCategoryId) ,

       mToyRate       money not null,

       cBrandId char(3)references ToyBrand(cBrandId),

       imPhoto image,

       siToyQoh       smallint not null,

       siLowerAge    smallint not null,

       siUpperAge     smallint not null,

       siToyWeight    smallint,

       vToyImgPath  varchar(50) null

)

insert into PremiumToys select * from Toys where mToyRate > 20

7.  对表Toys实施下面数据完整性规则:(1)玩具的现有数量应在0200之间;(2)玩具适宜的最低年龄缺省为1

    ALTER TABLE Toys

ADD CONSTRAINT siToyQoh_size check (siToyQoh>0 and siToyQoh <200)

ALTER TABLE Toys

ADD CONSTRAINT newsiLowerAge_min check (siLowerAge>=1)

8.  不修改已创建的Toys表,利用规则实现以下数据完整性:(1)玩具的价格应大于0;(2)玩具的重量应缺省为1

    CREATE RULE mToyRate_min

AS @mToyRate > 0

sp_bindrule 'mToyRate_min','Toys.mToyRate'

CREATE RULE siToyWeight_init

AS @siToyWeight = 0

Sp_bindrule ‘siToyWeight_init’,’Toys.siToyWeight’

9.  id为‘000001’玩具的价格增加$1

   update Toys set mToyRate=1+mToyRate where cToyId='000001'

10. 列出表PickofMonth中的所有记录,并显示中文列标题。

select cToyId as '玩具 id',siMonth as '出厂月份',iYear as '出厂年份', iTotalSold as '出厂总数' from PickOfMonth

 

实验二:查询数据库

 

1.         显示属于CaliforniaIllinoi州的顾客的名、姓和emailID

select vFirstName,vLastName,vEmailId

from Shopper

where cState='California' or cState='Illinoi'

2.         显示定单号码、商店ID,定单的总价值,并以定单的总价值的升序排列。

select cOrderNo,cCartId,mTotalCost

from Orders order by mTotalCost

3.         显示在orderDetail表中vMessage为空值的。

    select * from OrderDetail where vMessage is null

4.         显示玩具名字中有“Racer”字样的所有玩具的材料。

select vToyDescription

from Toys

where vToyName like '%Racer%'

5.         根据2000年的玩具销售总数,显示“Pick of the Month”玩具的前五名玩具的ID

select top 5 CToyId

from PickOfMonth

where iYear=’2000’ order by iTotalSold

6.         根据OrderDetail表,显示玩具总价值大于¥50的定单的号码和玩具总价值。

Select cOrderNO,mToyCost

from OrderDetail

where mToyCost > 50

7.         显示一份包含所有装运信息的报表,包括:Order Number, Shipment Date, Actual Delivery Date, Days in Transit. (提示:Days in Transit = Actual Delivery Date – Shipment Date)

select OrderNO,dShipmentDate,dActualDeliveryDate,DaysinTransit=datediff(day,dShipmentDate,dActualDeliveryDate)

from Shipment

8.         显示所有玩具的名称、商标和种类(Toy Name, Brand, Category)。

select vToyName,cCategory,cBrandName

from Toys ,Category ,ToyBrand 

where Toys.cCategoryId=Category.cCategoryId and Toys.cBrandId=ToyBrand.cBrandId

9.         以下列格式显示所有购物者的名字和他们的简称:(Initials, vFirstName, vLastName,例如Angela SmithInitialsA.S

    select

vFirstName,vLastName,Substring(vFirstName,1,1)+'.'+Substring(vLastName,1,1) as Initials

from Shopper

10.     显示所有玩具的平均价格,并舍入到整数。

    select round(avg(mToyRate),0) as AvgRate from Toys

11.     显示所有购买者和收货人的名、姓、地址和所在城市,要求显示结果集中的重复记录。

Select

a.vFirstName,a.vLastName,a.vAddress,a.cCity,b.vFirstName,b.vLastName,b.vAddress,b.cCity          

from Shopper a,Recipient b,Orders c

where a.cShopperId=c.cShopperId a.and b.cOrderNO=c.cOrderNO

12.     显示没有包装的所有玩具的名称。(要求用子查询实现)

select vToyName

from Toys

where cToyId

in (select cToyId from OrderDetail

where  cWrapperId is NULL)

13.     显示已发货定单的定单号码以及下定单的时间。(要求用子查询实现)

select cOrderNo,dOrderDate

from Orders where cOrderNo

in (select cOrderNo from Shipment

where dActualDeliveryDate is NOT NULL)

14.     显示一份基于Orderdetail的报表,包括cOrderNo,cToyIdmToyCost,记录以cOrderNo升序排列,并计算每一笔定单的玩具总价值。(提示:使用运算符COMPUTE BY)。

    select cOrderNo,cToyId,mToyCost

from Orderdetail

order by cOrderNo

compute sum(mToyCost) by cOrderNo

实验三:视图与触发器

 

1.         定义一个视图,包括购买者的姓名、所在州和他们所订购玩具的名称、价格和数量。
 create view ShopperandToys (vFirstName,vLastName,cState,vToyName,mToyRate,siQty)

as select a.vFirstName,a.vLastName,a.cState,b.vToyName,b.mToyRate,c.siQty

from Shopper a,Toys b,OrderDetail c,Orders d

where  (a.cShopperId=d.cShopperId and b.cToyId=c.cToyId) and c.cOrderNo=d.cOrderNo

结果:

2.         基于(1)中定义的视图,查询显示所有California州的购买者的姓名和他们所订购玩具的名称及数量。
select vFirstName,vLastName,vToyName,siQty

from ShopperandToys

where cState='California'

视图定义如下:
     CREATE VIEW vwOrderWrapper
     AS
     SELECT cOrderNo, cToyId, siQty, vDescription, mWrapperRate
     FROM OrderDetail JOIN Wrapper
     ON OrderDetail.cWrapperId = Wrapper.cWrapperId
以下更新命令,在更新siQtymWrapperRate属性使用了以下更新命令时出现错误:
     UPDATE vwOrderWrapper
     SET siQty = 2, mWrapperRate = mWrapperRate + 1
     FROM vwOrderWrapper
     WHERE cOrderNo = ‘000001’
修改更新命令,以更新基表中的值。

    UPDATE OrderDetail

     SET siQty = 2

     WHERE cOrderNo = '000001'

UPDATE Wrapper

     SET mWrapperRate = mWrapperRate + 1

     FROM OrderDetail a,Wrapper b

     WHERE a.cOrderNo='000001' and a.cWrapperId=b.cWrapperId

3.         OrderDetail上定义一个触发器,如果购物者改变了定单的数量,玩具的成本也自动地改变。(提示:Toy cost = Quantity * Toy Rate

    create trigger CheckToyCost

on OrderDetail

for update

as

if update(siQty)

     begin

      update OrderDetail

      set mToyCost=siQty*mToyRate

      f rom OrderDetail,Toys

     end

go

测试用例:

对定单的数量修改前的OrderDetail

对定单的数量进行修改:

修改后为:

4.         在(2)中定义的视图vwOrderWrapper上创建一个INSTEAD OF UPDATE触发器,以解决(2)中对视图进行更新时出现的问题。

实验四:存储过程

 

1.         编写一段程序,将每种玩具的价格提高¥0.5,直到玩具的平均价格接近$24.5为止。此外,任何玩具的最大价格不应超过$53

程序为:

use GlobalToyz

go

while (select avg(mToyRate) from Toys)<24.5

begin

  if (select max(mToyRate) from Toys)>53

    begin

      break

    end

  update Toys

  set mToyRate=mToyRate+0.5

end

程序执行前:

程序执行后:

2.         创建一个称为prcCharges的存储过程,它返回某个定单号的装运费用和包装费用。

创建存储过程的语句为:

create proc prcCharges @OrderNo char(6) output

as

select cOrderNo,mShippingCharges,mGiftWrapCharges

from Orders

where cOrderNo=@OrderNo

go

 

测试:

打开所创建的存储过程,输入想要查找的订单号

执行后的结果为:

使用另外一种测试方法:

 

 

3.         创建一个称为prcHandlingCharges的过程,它接收定单号并显示经营费用。PrchandlingCharges过程应使用prcCharges过程来得到装运费和礼品包装费。
提示:经营费用=装运费+礼品包装费

 

创建存储过程的语句为:

create proc prcHandingCharges @OrderNo char(6)

as

create table #temp1( OrderNo char(6), mSCharges money, mGCharges money)

insert into #temp1 exec prcCharges @OrderNo

select OrderNo,mSCharges+mGCharges as HandingCharges from #temp1

go

测试用列:

实验五:事务与游标

1.         名为prcGenOrder的存储过程产生存在于数据库中的定单号:
   CREATE  PROCEDURE  prcGenOrder
   @OrderNo char(6) OUTPUT
   as
   SELECT @OrderNo=Max(cOrderNo)  FROM Orders
   SELECT @OrderNo=
   CASE
      WHEN @OrderNo>=0 and @OrderNo<9 Then
              ‘00000’+Convert(char,@OrderNo+1)
      WHEN @OrderNo>=9 and @OrderNo<99 Then
              ‘0000’+Convert(char,@OrderNo+1)
      WHEN @OrderNo>=99 and @OrderNo<999 Then
              ‘000’+Convert(char,@OrderNo+1)
      WHEN @OrderNo>=999 and @OrderNo<9999 Then
              ‘00’+Convert(char,@OrderNo+1)
      WHEN @OrderNo>=9999 and @OrderNo<99999 Then
              ‘0’+Convert(char,@OrderNo+1)
      WHEN @OrderNo>=99999 Then Convert(char,@OrderNo+1)
   END
   RETURN
当购物者确认定单时,应该出现下面的步骤:
1)用上面的过程产生定单号。
2)定单号,当前日期,购物车ID,和购物者ID应该加到Orders表中。
3)定单号,玩具ID,和数量应加到OrderDetail表中。
4)在OrderDetail表中更新玩具成本。(提示:Toy cost = Quantity * Toy Rate.
将上述步骤定义为一个事务。编写一个过程以购物车ID和购物者ID为参数,实现这个事务。

该过程编写如下:

  create proc prcOrder @CartID char(6),@ShopperID char(6)

  as

  declare @OrderNo char(6),@OrderNo1 char (6),@ToyID char (6),@Qty char (6)

  exec prcGenOrder @OrderNo output

  SELECT @OrderNo1=isnull( CONVERT(nvarchar, @OrderNo), '' )

  create table #temp1

(OrderNo char (6),CartId char (6),ShopperId char (6),OrderDate datetime)

  insert into #temp1 (OrderNo,CartId,ShopperId,OrderDate)

values(@OrderNo1,@CartID,@ShopperID,getdate())

 insert into Orders (cOrderNo,cCartId,cShopperId,dOrderDate)

          select * from #temp1      

  select @ToyID=cToyId,@Qty=siQty from ShoppingCart

                 where cCartId=@CartID         

  insert into OrderDetail (cOrderNo,cToyId,siQty)

          values(@OrderNo1,@ToyID,@Qty)

  update OrderDetail

      set mToyCost=siQty*mToyRate

       from OrderDetail,Toys

  go

测试前的Orders

注意:订单号只是到000010

测试前的OrderDetail

对该过程进行测试:

注意:输入ToyIdShopperId都为:000001

执行后的结果为:

Orders表:

注意:订单号自动生成,为000011

OrderDetail表:

 

2.         编写一个程序显示每天的定单状态。如果当天的定单值总合大于170,则显示“High sales”,否则显示”Low sales”.报告中要求列出日期、定单状态和定单总价值。

程序为:

    declare @TotalCost money

select Orders.dOrderDate,Orders.cOrderProcessed,sum(mToyCost) as TotalCost

from Orders,OrderDetail

where Orders.cOrderNo=OrderDetail.cOrderNo and Orders.dOrderDate=getdate()

group by Orders.dOrderDate,Orders.cOrderProcessed

 

select @TotalCost=sum(mTotalCost)

from Orders,OrderDetail

where Orders.cOrderNo=OrderDetail.cOrderNo and Orders.dOrderDate=getdate()

if @TotalCost > 170

     print 'High Sales'

else

     print 'Low Sales'

 

你可能感兴趣的:(其他,数据库,wrapper,null,insert,测试,存储)