日期:2014-05-16  浏览次数:20374 次

机房收费系统数据库设计(二)

概述

数据库的设计老早就开始了,但是,今天才完成,我有点受不了,但也可以接收,因为集中在数据库设计的时间很少,接下的日子里,要开始UML画图阶段了,在这个阶段同样也是那样,重新的整体的来一遍,运用上三层的知识。下面说说数据库设计这方面的事情。

       数据库设计是一个反复的过程,在这个阶段了,光推到之前建好的静态数据库就有2次,小范围的修改就更是不用提,我相信在和应用程序连接的时候,还回有修改。

       自己设计的数据库运用了一些基本的技术,实现了数据无删除,真删除无知觉的功能,在设计的过程中遇到了一个误区,就是把最终应用程序和数据库管理程序的混淆了。最终的应用程序一方面受控于数据库管理程序的用户级别,另一方面受控于应用程序本身,而数据库管理程序只受控于用户级别。数据库的设计阶段要感谢李保强师哥和熊青峰师哥的帮助。下面是数据库运用到的一些技术。

触发器

        触发器的类型为Instead of中的Delete,由于数据库中有很多的外键约束关系,这样删除数据库的记录时,还需要知道数据库的中表和表之间的额关系,为了解决这个问题,创建这些触发器,通过级联和游标这些手段实现数据库管理系统的用户真删除数据简单化的功能。

       TI_Operator_Info触发器,操作者删除操作者的前一时刻触发。

USE [Charge]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

if exists(select * from dbo.sysobjects where id=OBJECT_ID(N'[dbo].[TI_Operator_Info]') and OBJECTPROPERTY(id, N'IsTrigger')=1)
drop trigger TI_Operator_Info
go

create trigger TI_Operator_Info on Operator_Info
instead of delete
as
   declare @Operator_ID char(20)
   declare @Operator_Login_ID int
begin
   --获得要删除的操作者的ID
   select @Operator_ID=Operator_ID  from deleted 
   
   --申明一个游标
   Declare Cur Cursor For 
   select Operator_Login_ID from Operator_Login_Record where Operator_ID=@Operator_ID
   
   --打开游标
   open Cur
   
   --使用游标
   fetch next from Cur into @Operator_Login_ID
   --删除该操作者的所有上机记录信息
   while @@FETCH_STATUS =0
         begin
              delete from Operator_Login_Record where Operator_ID =@Operator_Login_ID 
              fetch next from Cur into @Operator_Login_ID
         end
   
   --再删除操作者的信息
   delete from Operator_Info where Operator_ID=@Operator_ID 
end

注意:由于一个用户ID可能对应多条上机记录,要想全部的删除这些上机记录,需要使用游标,一个一个的删除;由于在这里只贴了一个触发器,看不出级联删除的意思,在这里叙述一些,要想真删除某一个操作者用户,必须先删除它的上机记录信息,要想删除他的上机记录信息,必须先删除它上机时的操作信息。


存储过程

       存储过程主要是为了最终的应用程序所使用,操作者的一些操作,都有相应的信息记录,所以,建立了相应的存储过程来实现目的

       Proc_AddOperator存储过程,操作者添加操作者时调用的一些T-SQL语句

--判断是否存在相同名称的存储过程
if (OBJECT_ID('Proc_AddOperator', 'P') is not null)
drop proc Proc_AddOperator
go

--创建存储过程
create proc Proc_AddOperator
(
    --操作者本次上机记录号
    @Operator_Login_ID int,
    --被操作者信息
    @Operator_ID varchar(20),
    @Operator_Key varchar(20),
    @Operator_Name varchar(20),
    @Operator_Sex varchar(20),
    @Operator_Level varchar(20)
)
as
    begin 
         --不返回受T-SQL语句影响的行数
         set nocount on
         --当事务中的语句出错时,事务回滚到事务的开始的那一状态
         set xact_abort on
         
         begin transaction --开始事务
         --先向注册记录表中写入数据,然后才可以向操作者信息表中写入数据
         --Operator_Register_ID为自增性
         insert into Operator_Register_Record(Operator_Login_ID ,Operator_User_ID ,Operator_Register_Date ,Operator_Register_Time ) 
         values(@Operator_Login_ID,@Operator_ID,CONVERT(varchar(10),GETDATE(),120),CONVERT(varchar(8),getdate(),108))
         
         --向Operator_Info表中写入数据
         insert into Operator_Info(Operator_ID ,Operator_Key ,Operator_Level ,Operator_Name ,Operator_Sex ,Operator_State )
         values(@Operator_ID ,@Operator_Key ,@Operator_Level ,@Operator_Name ,@Operator_Sex ,'离线')         
         
         commit tran
    end
go


       Proc_DaySum触发器用于汇总今天的总情况
描述:Proc_DaySum存储过程用于向DaySum中插入数据
if(OBJECT_ID('Proc_DaySum','P') is not null)
drop proc Proc_DaySum
go

create proc Proc_DaySum
(
    --操作者上机记录ID
    @Operator_Login_ID int
)
as
    declare @DaySum_Date date
    declare @DaySum_LoginN