第三部分应用案例 应用案例部分是在课程学习的基础上加以拓展,以培养数据库应用开发技术为目标,通过对一个数据库应用系统设计与实现过程的分析,帮助读者掌握开发SQL Server 2012数据库应用系统的一般设计方法与实现步骤。学习应用案例会对读者进行系统开发能起到示范或参考作用。下面以商场信息管理系统为例,介绍系统的设计与实现方法。通过本部分的学习,读者可以掌握如何以VB.NET为前端应用程序开发工具实现人机交互,以SQL Server 2012为后端服务器实现数据的处理。 1系统需求分析 商品信息管理系统主要实现对商品信息的管理,从实用的角度考虑,要求该系统实现如下功能。 (1) 系统登录功能: 负责程序的安全,使有合法身份的用户才能登录。 (2) 用户管理功能: 实现用户的管理,一般用户可以进入系统修改自己的密码,系统管理员可以添加新用户,设置新用户的权限。 (3) 商品信息录入功能: 实现对商品信息录入。 (4) 数据查询功能: 通过各种条件实现对已有的商品信息的查询操作。 (5) 数据修改功能: 实现对已有的数据进行修改、删除或添加新的商品信息。 (6) 数据显示功能: 使用图表方式向用户显示商品的库存数量。 2系统设计 商品信息管理系统的设计分为客户端设计和服务器端设计两部分。 2.1客户端设计 商品信息管理系统客户端的基本结构如图31所示。该系统要求实现的基本功能较为简单,主要实现对商品信息的录入和管理,包 图31客户端的基本结构 括用户管理、数据录入、数据修改、数据查询、库存信息5个界面。 程序员在开发客户端和服务器端程序时,首先必须知道客户端所需界面要求实现的基本功能,然后通过程序代码来实现。商品信息管理系统中各模块的基本功能如下。 (1) 用户管理模块: 主要用于录入用户的基本信息,其基本功能要求实现添加用户信息。 (2) 数据录入模块: 主要用于录入商品的详细信息,以便加强对商品的管理,其基本功能要求添加商品信息。 (3) 数据修改模块: 主要用于修改商品信息,并更新商品数据表。 (4) 数据查询模块: 主要通过表单形式查询所有商品的信息,其基本功能要求实现逐条记录查询,也可通过条件过滤进行查询,并可以对查询的信息进行修改或删除等操作。 (5) 库存信息模块: 通过图表的形式显示出当前库存中各商品的相关信息。 2.2服务器端设计 1. 数据信息分析与采集 根据前面的系统功能分析可知,该系统的数据来源主要是商品及用户信息。 (1) 商品基本信息: 主要存储商品的相关信息,包括商品的编号、名称、价格、单位、进货时间、数量、供应商等。本系统中许多对数据库的访问都是针对它的。 (2) 用户基本信息: 主要用于存储系统的用户信息,包括编号、用户名、密码、权限和权限等级等。应用程序根据用户等级进行数据库访问的安全控制。 根据系统功能分析及数据分析,确定本系统需要两个基本数据表,即商品信息表、用户信息表,其基本结构如图32和图33所示。 图32商品信息表 图33用户信息表 当用户修改商品信息时,需要记录一些简单信息,系统还需要商品信息修改记录表来存储这些信息。当用户修改商品信息时,该表由相应的触发器来填写,如图34所示。 图34商品信息修改记录表 2. 创建数据库与数据表 服务器端数据处理是通过SQL Server 2012管理平台来实现的,因此需通过SQL Server来创建数据库和数据表,操作步骤如下: (1) 启动SQL Server管理平台,在“对象资源管理器”窗口中选择“数据库”结点,右击,在弹出的快捷菜单中选择“新建数据库”命令,输入新建的数据库名称“商品信息管理系统”,单击“确定”按钮,新数据数据库成功。 (2) 此时,在“对象资源管理器”窗口中展开“数据库”→“商品信息管理系统”结点,在“表”结点上右击,在弹出的快捷菜单中选择“新建表”命令,弹出“表设计器”对话框,在该对话框中根据图32输入字段名称,并设置数据类型和大小,以“商品信息表”命名该表。 (3) 按照步骤(2),并根据图33和图34,新建“用户信息表”和“商品信息修改日志表”。 3系统实现 3.1SQL Server服务器端数据处理 通过对系统客户端界面的分析,知道了每个界面要求实现的基本功能,就可以开发服务器端数据处理程序。 在数据库商品信息管理系统中,用户修改商品信息由触发器tr_UpPrd和存储过程proc_Prd来完成,方法是: 当用户试图修改商品信息表时,触发器tr_UpPrd触发,触发器调用的存储过程proc_Prd将修改的商品编号和修改时间写入商品信息修改日志表中。 1. 存储过程proc_Prd设计 存储过程proc_Prd的作用是: 当触发器tr_UpPrd调用存储过程proc_Prd时,proc_Prd接收调用时参数传来的商品编号,并将该值写入商品信息修改日志表中,商品信息修改时间取默认值,即修改时的时间,由GETDATE()获得。创建存储过程proc_Prd的代码如下: USE 商品信息管理系统 IF EXISTS(SELECT name FROM sysobjects WHERE name='proc_Prd' AND type='p') DROP PROCEDURE proc_Prd Go CREATE PROCEDURE proc_Prd @编号int AS INSERT 商品信息修改表 VALUES(@编号,DEFAULT) GO 2. 触发器tr_UpPrd设计 触发器tr_UpPrd的作用是: 当用户删除、更新商品信息时,该触发器触发,触发器从deleted表中取出商品编号,并调用存储过程proc_Prd完成商品修改信息的记录。其代码如下: USE 商品信息管理系统 IF EXISTS(SELECT name FROM sysobjects WHERE name='tr_UpPrd' AND type='TR') DROP PROCEDURE tr_UpPrd Go CREATE TRIGGER tr_UpPrd ON 商品信息表 FOR DELETE,UPDATE AS DECLARE @编号 int SELECT @编号 = 编号 FROM deleted EXEC proc_Prd @编号 GO 3.2创建项目与主窗体 本系统使用VB.NET来开发应用程序,为用户提供访问数据库的界面。通过应用程序访问数据库,可以避免用户直接访问数据库,提高数据库的安全性,同时提供友好的人机交互界面使数据库管理人员更好地使用数据库。 1. 创建VB.NET项目与设置窗体属性 启动VB.NET开发环境后,选择“文件”→“新建项目”命令,在“新建项目”对话框中选择“项目类型”为Visual Basic,项目模板为“Windows窗体应用程序”,在“位置”文本框中输入Windows应用程序的位置,将项目命名为GoodsManagementSys,如图35所示,单击“确定”按钮进入VB.NET集成开发环境。 图35“新建项目”对话框 VB.NET自动生成一个窗体Form1,将其命名为MainWnd。选择“项目”→“GoodsManagementSys属性”命令,在“项目属性”对话框的“应用程序”选项卡中,取消选中“启用应用程序框架”,并在“启动对象”下拉列表中选择Sub Main项,当应用程序启动时,先调用名为Main的子程序,该Main子程序包含在项目的模块文件中。 在GoodsManagementSys项目属性对话框的“引用”选项卡中,导入命名空间中选择System.Data.SqlClient。 2. 创建项目模块 VB.NET中的模块可用来定义公共变量,同时也可用来启动程序。在本系统中,每个模块都会访问数据库,对数据的许多操作基本上是相同的。为此,可以将数据库的操作设计成一个被各模块调用的函数放入公共模块。另外,在多文档界面中,每次调用子窗体时,都要设置其在主窗体的位置,该位置就由一个公共函数来完成。 创建模块步骤如下: (1) 在“解决方案资源管理器”窗口的GoodsManagementSys项目上右击,在弹出的快捷菜单中选择“添加”→“模块”命令。 (2) 模块名称命名为ConfigModule。 (3) 在“解决方案资源管理器”中双击ConfigModule模块,打开代码设计窗口,在模块的全局说明区定义公共变量,代码如下: Public connectionString As String'连接字符串 Public username As String '登录用户名 Public intAuthority As Integer '权限值 (4) 在modulel模块中,定义Main子程序,当第一次进入应用程序时,Main子程序将激活,代码如下: Public Sub Main() Dim LoginWnd As New LoginWnd connectionString = "Data Source=(local);Initial Catalog=商品信息管理系统;Integrated Security=True" LoginWnd.ShowDialog() End Sub在Main子程序中定义了访问数据库商品信息管理系统的连接字符串connectionString,连接字符串中的数据源地址、用户名和密码根据实际情况进行修改,并启动LoginWnd窗体。 3. 创建主窗体 主窗体用于定位应用程序的不同部分,为应用程序提供导航功能。本系统采用多文档界面,使用户方便地在各个应用程序之间切换,且多文档窗体还可以少占系统资源。创建主窗体的一般步骤如下。 (1) 在项目GoodsManagementSys中添加一个窗体,窗体Name属性设置为MainWnd,Text属性设置为“商品信息管理系统”,IsMdiContainer属性设置为True,WindowState属性设置为Maximized,窗体界面如图36所示。 图36“商品信息管理系统”主窗体 (2) 在窗体上添加菜单。从工具栏中,将MenuStrip控件拖动到“商品信息管理系统”窗体中,菜单的标题、名称及调用的窗体名称如表31所示。 表31商品信息管理系统菜单的标题及调用的窗体名称 标题名称调用的窗体名称 用户管理mnUserUserManageWnd 数据录入mnuInsertGoodsInsertWnd 数据修改mnuUpdateGoodsUpdateWnd 数据查询mnuQueryGoodsQueryWnd 库存信息mnuStockGoodsStockWnd (3) 系统要求进行用户权限控制,控制的方法是在调用应用模块之前对用户的权限进行验证,若有权限调用该应用模块,则可进入主界面。例如,以下代码是对“数据录入”模块的权限验证及调用。 Private Sub mnuUpdate_Click(sender As Object, e As EventArgs) Handles mnuUpdate.Click If intAuthority = 1 Or intAuthority = 2 Or intAuthority = 4 Then Dim goodsUpdateWnd As New GoodsUpdateWnd goodsUpdateWnd.Show() Else MessageBox.Show("对不起,你没有相应的权限") End If End Sub 其他菜单命令也按此方法添加代码来实现调用,在调用前确定各模块的级别和权限等级,各模块级别及权限等级按其重要性进行编号,参见后面的表33。 3.3用户登录功能的实现 用户登录是为了确定该用户是否具备使用系统的权力及访问各模块的权限。登录时,用户输入用户名和密码,单击“登录”按钮, 图37“系统登录”窗体界面 应用程序将输入的用户名和密码与商品数据信息管理系统库的用户信息表中的已有用户信息进行比较,如果有相符的记录,则该用户有权进入系统,并确定该用户的权限等级,以便进行模块访问时验证。“系统登录”窗体界面如图37所示。 “系统登录”窗体的用户验证在“登录”按钮中执行,其代码如下: '定义全局变量currentUser、intAuthority,用于进入系统后的模块权限验证 Public intAuthority As Integer '权限值 Public loginUser As String '当前登录的用户 '当单击"取消"按钮时,执行btnCancel_Click()事件 Private Sub btnCancel_Click(sender As Object, e As EventArgs) Handles btnCancel.Click Me.Close() End Sub ' 当单击"登录"按钮时,执行btnLogin_Click()事件 Private Sub btnLogin_Click(sender As Object, e As EventArgs) Handles btnLogin.Click errorProvider.Clear() If txtBoxUsername.Text = "" Then txtBoxUsername.Text = "请输入用户名" txtBoxUsername.SelectAll() txtBoxUsername.Focus() Exit Sub End If If txtBoxPassword.Text = "" Then txtBoxPassword.Focus() Exit Sub End If Dim queryString As String = "SELECT * FROM 用户信息表 WHERE 用户名=(@Username) And 密码=(@Password)" Dim con As New SqlConnection(connectionString) Try con.Open() Catch ex As Exception MessageBox.Show("连接失败") Exit Sub End Try Dim cmd As New SqlCommand(queryString, con) cmd.Parameters.Add("@Username", SqlDbType.VarChar) cmd.Parameters("@Username").Value = txtBoxUsername.Text cmd.Parameters.Add("@Password", SqlDbType.VarChar) cmd.Parameters("@Password").Value = txtBoxPassword.Text Try Dim adapter As New SqlDataAdapter() adapter.SelectCommand = cmd Dim dataset As New DataSet adapter.Fill(dataset) If dataset.Tables(0).Rows.Count >= 1 Then username = txtBoxUsername.Text intAuthority = Convert.ToInt32(dataset.Tables(0).Rows(0).Item("权限等级")) Dim mainWnd As New MainWnd mainWnd.Show() Finalize() Else 'MessageBox.Show("登录失败") errorProvider.SetError(btnLogin, "用户名或者密码错误")