第八章、数据库后台编程技术

第八章、数据库后台编程技术

内容提要:

1、掌握存储过程的定义与使用

2、掌握用户定义函数的创建与使用

3、掌握触发器的定义与使用

4、掌握游标的定义与使用

第一节 存储过程

1、基本概念

使用T-SQL语言编写代码时,有两种方式存储和执行代码:

(1)在客户端存储代码,通过客户端程序或SQL命令向DBMS发出操作请求,由DBMS将结果返回给用户程序。

(2)以子程序的形式将程序模块存储在数据库中,供有权限的用户通过调用反复执行。

存储过程:即存储在数据库中供所有用户程序调用的子程序。

存储过程分为三类

系统存储过程

用户自定义存储过程(如果没有说明的话默认)

扩展存储过程

用户自定义存储过程

是由用户创建并能完成某一特定功能(如查询用户所需数据信息)的存储过程。本节将详细介绍用户自定义的存储过程。

以下三个存储过程即为用户自定义存储过程:

扩展存储过程

是 SQL Server 可以动态装载并执行的动态链接库 (DLL)。扩展存储过程使您得以使用象 C 这样的编程语言创建自己的外部例程。对用户来说,扩展存储过程与普通存储过程一样,执行方法也相同。

存储过程的优点

① 极高的执行效率。(所有的命令都是以批处理的方式处理)

② 增强代码的重用性和共享性。

③ 使用存储过程可以减少网络流量。

④ 使用存储过程保证安全性。

⑤ 在大型数据库中,应用程序访问数据库的最主要方式就是存储过程。

⑥ 存储过程可以在系统启动时自动执行。

2、创建、执行和删除存储过程

存储过程定义包含两个主要组成部分:

①过程名称及其参数的说明;

②过程的主体(其中包含执行过程操作的Transact-SQL语句)。创建存储过程的语法格式如下:

创建存储过程

CREATE PROCEDURE procedure_name [;number] /*定义过程名
[{@parameter data_type}                   /*定义参数的类型
[VARYING][ = default][OUTPUT]]            /*定义参数的属性
[,…n1]
[WITH {RECOMPILE | ENCRYPTION | RECOMPILE,ENCRYPTION}]
[FOR REPLICATION]                         /*执行的操作
AS sql_statement[,…n2]
/**
*RECOMPILE 是否重编译
*ENCRYPTION 是否加密
*FOR REPLICATION 是否不执行复制的存储过程
*/

执行存储过程

EXEC[UTE]
{   //返回状态
    [@return_status = ]
    //procedure_name,存储过程的组名
    //
   { procedure_name[;number] | @procedure_name_var}
   [ @parameter = ] { value | @variable[OUTPUT] | [DEFAULT]}
   [,…n]
   [WITH RECOMPILE]
}

【实例1】

建立查询某个指定地区购买了单价高于指定价格商品的顾客购买信息,列出顾客姓名,购买商品名,单价,购买日期,会员积分,其中默认地区是“长沙岳麓区”

CREATE PROCEDURE p_custbuy
@area varchar(20)=‘长沙岳麓区’,@Price money
AS
SELECT……FROM……JOIN……
WHERE [email protected] AND SaleUnitPrice>@Price
//执行:
EXEC  p_custbuy @Price=1000

【实例2】

建立统计某个指定地区和指定性别的顾客人数和平均年龄的存储过程,并将统计结果作为输出参数返回。

CREATE PROCEDURE p_custcout @area VARCHAR (20) , @sex CHAR @count INT output @avg_age INT output AS
SELECT
  @count = COUNT(*),
  @ave_age = AVG(YEAR(GETDATE ()) - YEAR(BIRTHDATE))
FROM
  Table_Customer
WHERE Address = @area
  AND Sex = @sex / / 执行: DECLARE @x INT,
  @y INT EXEC p_custcount ‘长沙岳麓区’,‘F’,
  @x output, @y output
  SELECT
    @x AS 人数, @y AS 平均年龄 

删除存储过程

DROP PROCEDURE [PROCEDURE_NAME]

实例:

DROP PROCEDURE p_custbuy
DROP PROCEDURE p_custcout
DROP PROCEDURE p_update

第二节 用户定义函数

用户定义函数:

  类似于编程语言中的函数,其结构与存储过程类似,但函数必须有一个RETURN子句,用于返回函数值。

两类用户定义函数:

  标量函数和表值函数。前者返回单个数据值,表值函数返回一个表。

1、创建和调用标量函数

//定义标量函数:
CREATE  FUCTION ……RETURNS return_data_type
AS
BEGIN
//【函数体】
  RETURN scalar_expression
END

【实例】

创建查询指定商品类别的商品种类数的标量函数。

CREATE FUCTION dbo.f_GoodsCount (@class VARCHAR (10)) RETURN INT AS
BEGIN
  DECLARE @x INT
  SELECT
    @x = COUNT(*)
  FROM
    Table_GoodsClass a
    JOIN Table_Goods b
      ON a.GoodsClassID = b.GoodsClassID
  WHERE GoodsClassName = @class RETURN @x
  END 

调用标量函数:

注意:

调用时需要提供函数拥有者名和函数名;

可以在任何出现表达式的SQL语句中调用类型一致的标量函数。

【实例】

查询“服装”类商品的名称和种类数量

SELECT GoodsName AS 商品名,dbo.f_GoodsCount(‘服装’)AS 种类数
FROM……WHERE……

2、创建和调用内嵌表值函数

创建内联表值函数:

CREATE FUCTION ……RETURNS TABLE
AS
RETURN [(]select_stmt[)]

参数说明:select_stmt是定义内联表值函数返回值的单个SELECT语句;表值函数没有返回变量,没有函数体,只返回一个查询结果。

调用内联表值函数:

使用内联表值函数与视图类似,其作用相当于带参数的视图。

【实例】

创建查询指定类别的商品名和单价的内联表值函数。

CREATE FUCTION f_GoodsInfo (@class CHAR(10)) RETURNS TABLE AS RETURN
(SELECT
  GoodName,
  SaleUnitPrice
FROM
  Table_GoodClass a
  JOIN Table_Goods b
    ON a.GoodsClassID = B.GoodsClassID
WHERE GoodClassName = @class)
/ / 调用:
SELECT
  *
FROM
  dbo.f_GoodsInfo (‘服装’)

3、创建和调用多语句表值函数

CREATE FUCTION ……RETURNS @return_variable TABLE<table_type_definition定义返回的表结构>
AS
BEGIN
【函数体:SQL语句】
 RETURN
END

调用建多语句表值函数:在SELECT的FROM子句中使用。

【实例】

创建查询指定类别的商品名、单价、生产日期和商品种类的多语句表值函数。

CREATE FUCTION f_GoodsDatails (@class VARCHAR (20)) RETURNS @f_GoodsDatails TABLE( 商品名 varchar(50), 单价 money, 生产日期 datetime, 种类数 int) AS
BEGIN
  INSERT INTO @f_GoodsDatails
  SELECT
    GoodName,
    SaleUnitPrice,ProductionDate,dbo.f_GoodsDatails (@class)
  FROM
    Table_GoodClass a
    JOIN Table_Goods b
      ON a.GoodsClassID = B.GoodsClassID
  WHERE GoodClassName = @class) RETURN
  END
  //调用:
  SELECT * FROM dbo.f_GoodsDatail(‘服装’)

4、删除用户自定义函数

DROP FUNCTION

实例

DROP FUNCTION f_GoodsCount

DROP FUNCTION f_GoodsInfo

DROP FUNCTION f_GoodsDatails

第三节 触发器

1、基本概念

  触发器:特殊存储过程,在对表中的数据进行UPDATE、INSERT、DELETE操作时自动触发执行,常用于保证业务规则和数据完整性,增强数据完整性约束能力。

SQL Server 2008支持三种类型的触发器:

  DML(数据操纵由于)、DDL(数据定义语言)、登录触发器。

适用场合:

  1. 完成比CHECK(只能实现同一表列之间取值约束)约束更复杂的数据约束。
  2. 保证数据库性能而维护的非规范化数据。
  3. 可实现复杂的商业规则。
  4. 评估数据修改前后的表状态,并采取对策。

2、创建触发器

CREATE TRIGGER trigger_name ON
{ table | view }
[WITH ENCRYPTION]
{ FOR | AFTER | INSTEAD OF }
{ [ INSERT ] [ , ] [ UPDATE ] [ , ]
[ DELETE ] }
AS
sql_statement[…n]

参数说明:

FOR或AFTER:后触发型,操作、约束检查完成后触发。

INSTEAD OF :前触发型,数据操作语句最多定义一个触发器。执行触发器而非引发语句。若满足完整性约束则需要重新执行这些数据操作。

注意

  一个表可建多个触发器,每个触发器可由三个操作触发。ALTER类型同一操作上建立多个触发器,INSTEAD OF类型同一操作上建立一个触发器。

? 所有建立和更改数据库以及数据库对象的语句、DROP语句不允许在触发器中用。

  触发器不要返回任何结果。

在触发器中有两种逻辑表

instead表和deleted

instead保存插入之前的数据

deleted保存的是删除之后的数据

【实例1】

维护不同列的取值完整性的触发器。保证“商品表”中单价列值与“商品价格变动表”中单价列值一致。

CREATE TRIGGER UnitPriceConsistent
ON Table_PriceHistory FOR
INSERT,
UPDATE AS DECLARE
  @NewPrice money
  SELECT
    @NewPrice = SaleUnitPrice
  FROM
    inserted
    UPDATE
      Table_Goods
    SET
      SaleUnitPrice = @NewPrice
    WHERE GoodsID IN
      (SELECT
        GoodsID
      FROM
        inserted)

【实例2】

创建只允许删除会员卡积分低于500分的顾客记录的触发器。

CREATE TRIGGER DeleteCust
ON Table_Customer INSTEAD OF
DELETE AS IF NOT EXISTS
  (SELECT
    *
  FROM
    deleted
  WHERE CardID IN
    (SELECT
      CardID
    FROM
      Table_Card
    WHERE Score >= 500))
  DELETE
  FROM
    Table_Customer
  WHERE CardID IN
    (SELECT
      CardID
    FROM
      deleted)

E:\User\shaoyayu\2020-2021上学期学习材料\计算机三级数据库\38468444\18\64

3、删除触发器

DROP TRIGGER

实例

DROP TRIGGER OperateCon

DROP TRIGGER UnitPriceConsistent

DROP TRIGGER DeleteCust

第四节 游标

游标:实现对SELECT结果集的逐行处理。

1、游标的组成

  游标结果集(SELECT返回结果集)与游标当前行指针(指向结果集中某一行)

  特点:定位特定行;从当前位置检索一行或多行;支持当前行数据修改;对修改结果提供不同级别的可见性支持

2、使用游标

(1)声明游标

  ISO标准语法:DECLARE cursor_name[1] CURSOR FOR select_statement[2]

  参数说明:[1]INSENSTITIVE:创建临时副本,对临时表操作,否则对基本表;SCROLL:范围,否则只支持NEXT;[2]READ ONLY:禁止更新 UPDATE 更新列指定列或所有。

(2)打开游标

  OPEN cursor_name

(3)提取数据

  FETCH [1]FROM cursor_name [INTO @ variable_name[,…n]]

(4)关闭游标

  CLOSE cursor_name

   可以再次打开。

(5)释放游标

  DEALLOCATE cursor_name

  释放分配给游标的所有资源。

3、游标示例

 对Table_Customer表,定义一个查询“长沙岳麓区”姓“王”的顾客姓名和邮箱的游标,并输出游标结果。

DECLARE @cn VARCHAR (10 @cn VARCHAR (50) DECLARE Cname_cursor CURSOR FOR
SELECT
  Cname,
  Email
FROM
  Table_Customer
WHERE Cname LIKE ‘王 % ’AND Address LIKE ‘长沙岳麓区’ OPEN Cname_cursor FETCH NEXT
FROM
  Cname_cursor INTO @cn,
  @Email
  WHILE
    @@ FETCH_STATUS = 0
    BEGIN
      PRINT’顾客姓名’ + @cn + ‘,邮箱:’ + @Email FETCH NEXT
FROM
  Cname_cursor INTO @cn,
  @Email
END CLOSE Cname_cursor DEALLOCATE Cname_cursor 

例题

1、在SQL Server 2008中,对于更新操作的触发器,系统将产生2张逻辑工作表,其中存放更新前数据的逻辑工作表是(  )。
答案:DELETE
更新就是
1、删除原数据
2、插入数据
2、删除用户自定义的函数使用(  )语句来实现。
答案:DROP FUNCTION
3、设在数据库应用系统设计与实现过程中有下列活动:
Ⅰ. 创建触发器
Ⅱ. 定义事务隔离性级别
Ⅲ. 数字签名
Ⅳ. 定义主码
上述活动中,用于数据库的完整性保护的是(  )
A.仅Ⅰ和Ⅳ          B.仅Ⅰ和Ⅱ
C.仅Ⅲ和Ⅳ          D.仅Ⅱ和Ⅲ
答案:B
4、利用游标机制可以实现对查询结果集的逐行操作。下列关于SQL Server 2008中游标的说法中,错误的是(  )
A. 每个游标都有一个当前行指针,当游标打开后,当前行指针自动指向结果集的第一行数据
B.如果在声明游标时未指定INSENSITIVE选项,则已提交的对基表的更新都会反映在后面的提取操作中
C.当@@FETCH_STATUS=0时,表明游标当前行指针已经移出了结果集范围
D.关闭游标之后,可以通过OPEN语句再次打开该游标
答案:C
5、在SQL Server 2008中,用于判断游标数据提取状态的全局变量是(  )。
答案:@@FETCH_STATUS
6、设在SQL Server 2008某数据库中有按如下格式定义的存储过程首部:
CREATE PROC P1
@x int, @y int, @z int output AS ...
请补全下列调用该存储过程的语句。
DECLARE @S int
EXEC P1 20, 30, @S  (  )
答案:output  
7、在SQL Server 2008中,设有教师表(教师号, 姓名, 所在部门号, 职称)和部门表(部门号, 部门名, 高级职称人数)。请编写满足下列要求的后触发型触发器(设触发器名字为tri_zc)。
  每当在教师表中插入一名具有高级职称("教授"或"副教授")的教师时,或者将非高级职称教师的职称更改为高级职称时,均修改部门表中相应部门的高级职称人数。(假设一次操作只插入或更改一名教师的职称) )

【解题思路】创建触发器的SQL语句为:CREATE TRIGGER
  根据原题要求,insert触发器会在inserted表中添加一条刚插入的记录,update触发器会在更新数据后将更新前的数据保存在deleted表中,更新后的数据保存在inserted表中。在教师表中插入或者更新的时候,都会在inserted表中增加一条记录,所以只需在触发器查询inserted表中查询有没有"教授"或者"副教授"的记录,如果有,则触发修改相应部门的高级职称人数即可。
//答案
CREATE TRIGGER tri_zc
ON 教师表 AFTER INSERT,
UPDATE AS
  BEGIN
    DECLATE @zc VARCHAR (10),
    @dept VARCHAR (30)
    SELECT
      @dept = 所在部门号, @2 c = 职称
    FROM
      inserted IF @zc = ′教授′
      OR ′副教授′
      UPDATE
        部门表
      SET
        高级职称人数 = 高级职称人数 + 1
      WHERE 部门号 = @dept
      END 
8、设在SQL Server 2008某数据库中有商品表和销售表,两个表的定义如下:
CREATE TABLE 商品表 (
  商品号 CHAR(10) PRIMARY KEY,
  商品名 VARCHAR (40),
  类别 VARCHAR (20),
  进货单价 INT
);
CREATE TABLE 销售表 (商品号 CHAR(10),
  销售时间 DATETIME,
  销售数量 INT,
  销售单价 INT,
PRIMARY KEY (商品号, 销售时间))

下面是一个用户定义的多语句表值函数,它接受类别作为输入参数,返回该类别下的每种商品在2012年的销售总利润,并将结果按照销售总利润的降序输出。请补全该函数定义代码。 

CREATE FUNCTION f_Profit (@lb char(10))  【1】@ProfitTable【2】(
商品号 char(10),
总利润 int )
AS
BEGIN
  INSERT INTO @ProfitTable
【3】
【4】
END
第一空:RETURNS
第二空:table
第三空:
a
SELECT
  a.商品号,
  SUM(
    销售数量 * (销售单价 - 进货单价)
  ) AS总利润
FROM
  销售表 a JOIN商品表b
  ON a.商品号 = b.商品号
WHERE a.商品号 IN
  (SELECT
    商品号
  FROM
    商品表
  WHERE 类别 = @lb)
GROUP BY a.商品号ORDER BY 总利润 DESC 

第四空:[email protected] Table

原文地址:https://www.cnblogs.com/shaoyayu/p/12424136.html

时间: 2024-08-14 07:32:54

第八章、数据库后台编程技术的相关文章

Manual | BSD手册| Linux手册 | 数据库手册 | 编程开发手册 | WEB开发手册 | 软件应用手册 | 网络技术手册 | GNU手册

豆豆手册 □ BSD手册 □ Linux手册 □ 数据库手册 □ 编程开发手册 □ WEB开发手册 □ 软件应用手册 □ 网络技术手册 □ GNU手册 在线手册 首 页 BSD手册 ·FreeBSD Handbook 简体中文版 ·NetBSD Internals ·NetBSD 指导手册 ·FreeBSD Porter 手册 ·FREEBSD 使用者手册 ·FreeBSD 5.x 架设管理与应用 ·FreeBSD 6.0架设管理与应用 ·OpenBSD FAQ中文版 Linux手册 ·Turb

计算机编程技术蓝图

目录: 0 硬件 1 基本概念 2 操作系统 3 编程技术  4 软件工程 5 高效的程序员 6 编程实践   自己主要关注2个方面,硬件方向的单片机(如何与各种硬件外设交互)和软件方向的计算机图形学(专注于图形图像的生成).其他还关心linux,网络. 从0开始 :) 0 硬件 对于一个计算机硬件,我们需要从哪些方面了解呢?以下是个列表(链接待整理). 模块 硬件 编程方面 接口方式 衡量指标 研究方向 处理器 pc,notebook,phone 线程 intel: Socket 478 ,L

新一代编程:scala泛函编程技术-唠叨

准备了半年后,终于决定在这里开始我的scala编程技术学习体验撰写之旅.初步打算在这里把我学习.体验.掌握scala编程的过程与有兴趣的朋友分享.我想,虽然我这不是正式论文或者教课书之类的,但写个开场白总是好的.以后都是技术性的表述了,还是把握最后机会唠叨一下吧... 刚好完成了一个行业云平台项目,决定暂停下来仔细思考一下下一步应该怎么走,是不是要改改方向?在之前的项目里,作为项目开发负责人,为了保证项目的成功率,必须完全依赖公司现有的技术.技能资源,绝不能轻易引进新的技术线路和手段,所以眼睁睁

利用JSP编程技术实现一个简单的购物车程序

实验二   JSP编程 一.实验目的1. 掌握JSP指令的使用方法:2. 掌握JSP动作的使用方法:3. 掌握JSP内置对象的使用方法:4. 掌握JavaBean的编程技术及使用方法:5. 掌握JSP中数据库编程方法: 二.实验要求 : 利用JSP编程技术实现一个简单的购物车程序,具体要求如下. (1)用JSP编写一个登录页面,登录信息中有用户名和密码,分别用两个按钮来提交和重置登录信息. (2)编写一个JSP程序来处理用户提交的登录信息,如果用户名为本小组成员的名字且密码为对应的学号时,采用J

构建施耐德楼控系统数据库后台服务器示例工程二(数据库查询编写)

构建施耐德楼控系统数据库后台服务器示例工程-(工程创建)记录了一个Spring.Hibernate.Rest的工程如何创建,这篇将简单介绍在这个框架下如何利用注释编程. 1.Spring注释 Spring为我们提供了@Service.@Autowired这些标注来让工程中的Bean自动创建. 在我们的框架中,我们需要为每一个需要被其他类调用到的类名前添加@Service标签,在需要被自动创建的成员类上添加@Autowired,这样程序在运行时Spring会为我们自动装配相关的类实例. 2.Res

[JAVA_开课吧资源]第五周 I/O操作、多线程、网络编程技术

主题一 I/O操作 » 流的概念 在面向对象语言中, 数据的输入和输出都是通过数据流来实现的.数据流是一组有顺序.有起点和终点的字符集合.就好比是两个不同的池子,一个池子中存满了水,而另一个池子中则没有任何的东西,在这两个水池中安放一个管子,水就可以从一个池子流向另一个池子了.在从一个池子向另一个池子输送水的过程中,水扮演的角色就是数据流. [请点击查看更多内容 转自文章] » Stream stream代表的是任何有能力产出数据的数据源,或是任何有能力接收数据的接收源.在Java的IO中,所有

编程技术日新月异,TAOCP经典永驻

1968年,C语言还未出现,鼠标刚刚问世,ARPAnet还在酝酿之中. 2017年,编程语言多达几百种,PC走进千家万户,ARPAnet已经退役十多年. 1968年,有一套关于编程的图书出版了第1卷. 2017年,这套书仍然是科技领域的经典. 这就是<计算机程序设计艺术>. <计算机程序设计艺术>简写为TAOCP. 1962年,编程界先驱高德纳开始写作<计算机程序设计艺术>.他原本只打算写12章,谁知道一写就是几十年,一本书变成了一部"史诗". 19

IOS开发-多线程编程技术(Thread、Cocoa operations、GCD)

前言:在软件开发中,多线程编程技术被广泛应用,相信多线程任务对我们来说已经不再陌生了.有了多线程技术,我们可以同做多个事情,而不是一个一个任务地进行.比如:前端和后台作交互.大任务(需要耗费一定的时间和资源)等等.也就是说,我们可以使用线程把占据时间长的任务放到后台中处理,而不影响到用户的使用. 线程的定义: 每个正在系统上运行的程序都是一个进程.每个进程包含一到多个线程.进程也可能是整个程序或者是部分程序的动态执行.线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行.也可以把它理

.NET 线程池编程技术

摘要 深度探索 Microsoft .NET提供的线程池, 揭示什么情况下你需要用线程池以及 .NET框架下的线程池是如何实现的,并告诉你如何去使用线程池. 内容 介绍 .NET中的线程池 线程池中执行的函数 使用定时器 同步对象的执行 异步I/O操作 监视线程池 死锁 有关安全性 结束 介绍 如果你有在任何编程语言下的多线程编程经验的话,你肯定已经非常熟悉一些典型的范例.通常,多线程编程与基于用户界面的应用联系在一起,它们需要在不影响终端用户的情况下,执行一些耗时的操作.取出任何一本参考书,打