数据库程序设计中的约束、触发器和存储过程_zhang_xinxiu的博客-程序员宅基地

技术标签: SQL数据库  encryption  insert  存储  【SQL数据库】  数据库  delete  sql server  

       上篇博客中所说的对于表操作的几种限制少分析了触发器。这次从对表设计的角度来着重分析约束和触发器的关系,并进一步扩展比较触发器和存储过程。但在看该篇博客前强烈建议大家好好读下我的上一篇博客约束与数据库对象规则、默认值的探究

       首先,从图上来比较三者的关系:

       触发器不仅能够保证数据的完整性,而且还可以封装复杂的T-SQL逻辑处理语句,在功能上类似于存储过程,所

以触发器又是一种特殊的存储过程。但是存储过程的执行是我们使用Exec主观调用的,而触发器是经过一种事件操作

后自动被调用的。

      在拆开分析约束和触发器、触发器和存储过程之前我们穿插点外话。在数据库程序设计中包含有多种数据模型:

20世纪60年代后期,在文件系统基础上发展起来的层次模型、网状模型和关系模型等传统数据模型;20世纪70年代

后期产生的E-R数据模型;20世纪80年代以来又相继推出面向对象数据模型、基于逻辑的数据模型等新的模型。下

图关系数据库中的关键术语和语义对象模型及ER图中使用的术语之间的映射关系:

 

数据库中正式术语

文件

SOM

E-R

关系

文件

实体集合

元组

记录

对象

实体

属性

属性

属性

 

         上面的内容只存在了解而已,不用深究。

●数据完整性和业务规则

          在上篇博客我已经简单介绍了数据完整性,接下来我们详细说下数据完整性和业务规则。

      一、数据完整性

              数据完整性=可靠性+准确性,这里我们要清楚一下两点:

                  •    数据存放在表中

                  •   创建表的时候,就应当保证以后数据输入是正确的(错误的数据、不符合要求的数据不允许输入)

              为了保证数据的完整性我们经常使用完整性约束来确保数据的完整性。数据完整性,主要包括下面四部分:

      二、业务规则

            业务规则听起来很难理解,当然它也是值得我们深究东西,通俗的讲它其实是符合实际条件。如:某商店规定

一个售货员在一个月内售出10个以上的热浴盆,那么奖励2000元;某公司的订单上必须含有客户的姓名和联系方式等

等,这些都是简单的业务规则。从数据库的角度看,业务规则就是约束。

●约束和触发器

         MS SQL Server提供了两种主要的机制进行强制业务规则和数据的完整性:约束和触发器。在作用上约束支持的触

发器都可以实现,它们两者是相容的关系,如下图。虽然两者在作用关系上有重合的地方,但是相较两者的执行效率

和维护难易来说,触发器是远远不如约束的。所以约束能实现的情况下编程人员是不会选择触发器的。

                                                                                       

         一、约束,上篇博客我已经着重讲解了约束的概念,这里不再深究。

                     SQL Server中存在五种约束:

                             •  约束的目的:确保表中数据的完整型

                             •  常用的约束类型:

                                   –        主键约束(Primary Key Constraint):要求主键列数据唯一,并且不允许为空

                                   –        唯一约束(Unique Constraint):要求该列唯一,允许为空,但只能出现一个空值。

                                   –        检查约束(Check Constraint):某列取值范围限制、格式限制等,如有关年龄的约束

                                   –        默认约束(Default Constraint):某列的默认值,如我们的男性学员较多,性别默认为

                                   –        外键约束(Foreign Key Constraint):用于两表间建立关系,需要指定引用主表的那列

            二、触发器,首先在下表中来看触发器的基本结构。

              触发器是一种对表进行插入、删除、更改的时候自动运行的特殊的存储过程。它一般用在比核查约束更为复杂

的约束中。但能用约束实现的功能,一般不用触发器。

           接下来我们从代码中认识下几种触发器。

       --#Update型触发器
	If exits(select name from sysobjects where name=’tgr_update’)
	Drop trigger tgr_update
	Go
	Create trigger tgr_update on student
		for update
	As
		If (Update(student_ID))
			Print ‘更改成功!’
		Else
			Begin 
				Raiserror(‘系统提示:更新发生错误’,16,1)
				Rollback tran
			End
	Go
	--测试
	Update student set student_ID=10002 where student_ID=10001       

                 注意:在创建触发器时,创建触发器必须是批处理的第一行,存储过程也是如此。

     --# instead of 触发器
          if (object_id('tgr_classes_inteadOf', 'TR') is not null)
           drop trigger tgr_classes_inteadOf
         go
         create trigger tgr_classes_intead Of
               on classes
         instead of delete/*, update, insert*/
         as
            declare @id int, @name varchar(20);
            --查询被删除的信息,病赋值
              select @id = id, @name = name from deleted;
            print 'id: ' + convert(varchar, @id) + ', name: ' + @name;
            --先删除student的信息
              delete student where cid = @id;
            --再删除classes的信息
              delete classes where id = @id;
            print '删除[ id: ' + convert(varchar, @id) + ', name: ' + @name + ' ] 的信息成功!';
         go
         --test
         select * from student order by id;
         select * from classes;
         delete classes where id = 7;
 

     # 启用、禁用触发器

     --禁用触发器
       disable trigger tgr_message on student;
     --启用触发器
       enable trigger tgr_message on student;

# 显示自定义消息raiserror

   if (object_id('tgr_message', 'TR') is not null)
        drop trigger tgr_message
   go
   create trigger tgr_message
        on student
      after insert, update
   as raisError('tgr_message触发器被触发', 16, 10);
   go
   --test
   insert into student values('lily', 22, 1, 7);
   update student set sex = 0 where name = 'lucy';
   select * from student order by id;

 

      触发器的应用种类繁多上面的几个示例都是比较常用的,当然最好的熟练方法就是多用,多练。

●触发器和存储过程

         触发器是一种特殊的存储过程,不是由用户直接调用。而存储过程是一组T-SQL语句,经过编译后可以被多次调

用。类似于其它编程语言中的过程。它可以接收输入参数、输出参数、

      返回单个或多个结果集以及返回值。

             存储过程分为三类:

                     1.系统存储过程:以sp_开头,用来进行系统的各项设定.取得信息.相关管理工作,

                                      sp_help就是取得指定对象的相关信息

                     2.扩展存储过程  XP_开头,用来调用操作系统提供的功能

                                     exec master..xp_cmdshell 'ping 10.8.16.1'

                     3.用户自定义的存储过程,这是我们所指的存储过程     

                     常用格式

Create PRocedure procedue_name
   [@parameter data_type][output]
   [with]{recompile|encryption}
   as
        sql_statement
--解释:  
--output:表示此参数是可传回的
--with {recompile|encryption}
--recompile:表示每次执行此存储过程时都重新编译一次
--encryption:所创建的存储过程的内容会被加密

 

举例:

       有如下表量表

result_Info

 

Student_ID

Name

result

1

张红

70

2

马力

80

       Student_Info

Student_ID

Sex

Grade

1

一年级

2

二年级

 

      #创建返回参数的存储过程

If exists(select name from sysobjects where name=’proc_return’ and type=’P’)
	Drop proc proc_return
	Go
	Create proc proc_return  
@param1 int,
			@param2 char(10),
			@param3 char(10)
			@param4 int output
	With encryption    --加密
	As
		Insert into student_Info(student_ID,name,result) values(@param1,@param2,@param3)
		Select @param4=sum(result) from student_Info
		Print ‘总分为:’ & convert(char,@param)
	Go
	--调用测试
	Declare @sumresult int
	Exec proc_return 12,’王刚’,80,@sumresult
	Go


          存储过程的3种传回值:

                    1.Return传回整数

                    2.output格式传回参数

                    3.Recordset

         传回值的区别:

                       outputreturn都可在批次程式中用变量接收,recordset则传回到执行批次的客户端中 

       #创建一个存储过程,实现将表一和表二合并,该表只含Student_IDNamesexresult,将临时表存放在存储过

程中。

If exists(select name from sysobjects where name=’proc_save’ and type=’P’)
	Drop proc proc_return
	Go
	Create proc proc_save
	As	
		Select r.student_ID,r.Name,r.result,s.sex into #temptable from result r inner join student s on                 r.student_ID=s.student_ID
	If @@error=0
		Print ‘Successed’
	Else
		Print ‘Failed’
	Go

          存储过程的应用类型还有很多,这里我只介绍了在编程时常用的两种。

●总结

       在进行数据库程序设计时,数据的完整性是编程人员必须要考虑的,但是有时候这些知识的细节却让我们纠结的

很,搞不清改用哪个。总之吧:能用存储过程实现的不用触发器;能用约束实现的不用触发器,约束和存储过程用哪

个都可以。

        有些不懂得地方在SQL Server中按F1,在SQL Server联机丛书的索引中查找可以解决我们的一切矛盾。


 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhang_xinxiu/article/details/7875047

智能推荐

本地摄像头应用到远程计算机,远程摄像头设置-程序员宅基地

可以的,智能家用监控摄像头,只要你手机有网,千里之外打开手机都可以查看视频,而且智能摄像头主要用于看家看孩子看老人照看猫猫狗狗等宠物的。智能摄像头,与市面上普通的事件录制不一样,它可以实现7*24小时不间断录制,并对录制的视频内容传输至云端,我们通过手机APP就能随时随地查看家中情况,隐秘、安全、智能,可视,哪怕本人出差在千里之外的异地,都可以随时打开手机APP,孩子的一举一动都能尽收眼底。当然上..._本地监控至远程监控

关于网卡及MAC和PHY的区别,讲的比较清楚(转帖)_网卡和phy的区别_天马行空_xaut的博客-程序员宅基地

一块以太网网卡包括OSI(开方系统互联)模型的两个层。物理层和数据链路层。物理层定义了数据传送与接收所需要的电与光信号、线路状态、时钟基准、数据编码和电路等,并向数据链路层设备提供标准接口。数据链路层则提供寻址机构、数据帧的构建、数据差错检查、传送控制、向网络层提供标准的数据接口等功能。1.网卡的基本结构 以太网卡中数据链路层的芯片一般简称之为MAC控制器,物理层的芯片我们简称之为PHY。许多网卡的芯片把MAC和PHY的功能做到了一颗芯片中,比如Intel 82559网卡的和3COM 3C..._网卡和phy的区别

简答题——heap和stack的区别-程序员宅基地

Heap和Stack的区别? 1.heap是堆,stack是栈。 2.stack的空间由操作系统自动分配和释放,heap的空间是手动申请和释放的,heap常用new关键字来分配。 3.stack空间有限,heap的空间是很大的自由区。在Java中,若只是声明一个对象,则先在栈内存中为其分配地址空间,若再new一下,实例化它,则在堆内存中为其分配地址。_heap和stack的区别

于飞SEO:如何把子目录里面的文件批量移动到根目录呢?-程序员宅基地

由于工作上的需求,需要把子目录里面的文件全部移动到根目录,如果一个文件一个文件的单独复制的话,量少还好,但是如果量很大的话,就太费功夫了,很不现实。那么如何把子目录里面的文件批量移动到根目录呢?这里我们用的是便捷的计算机命令,这个命令操作是把所有文件夹内的文件给释放到根目录,所以有个弊端就是同名的文件会出现替换问题,注意操作,出现误操作了不要怪我哦,而且是所有的子目录文件,哪怕文件夹内的文...

NLP——7.LDA主题模型(数学公式推导)_lda一致性计算公式-程序员宅基地

这篇文章看一下公式式怎么推导出来的。正经的LDA,主要有以下几个方面:一个函数:gamma函数四个分布:二项分布,多项分布,beta分布,狄利克雷分布一个概念一个理念:共轭先验与贝叶斯框架pLSA,LDA一个采样:Gibbs采样我们来看一下它是怎么推导出来的。共轭先验与共轭分布假定似然函数p(x|θ)p(x|θ)已知,问题是选取什么样的先验分布p(θ)p(θ)和后验分布p(..._lda一致性计算公式

抖音账号盘子起底:摄影类账号是怎么割韭菜?_做图片的主播为什么这么少_大力财经的博客-程序员宅基地

抖音上有这么一类主播,不用露脸,不用跟观众互动,一天能挣个大几万。这群主播就是搞手机摄影盘的人。这个盘子咱先从起盘人说起。首先起盘人会先做一个手机摄影账号,那么账号的视频端内容方面就是做一些剪映模板,挂上剪映小程序,获得推广收益。这类账号半小时就能完成一条视频,一条收入100~1000,一天剪个三条视频,视频端一天的收入至少都300块。不过,视频端的作用远远不止这点小钱,它在直播卖课的时候,有更大的作用。在直播间,主播就会用固定的模式(也就是风险厌恶模型),走三个流程。第一个流程就是展..._做图片的主播为什么这么少

随便推点

Vue中的消息订阅与发布(pubsub)_"pubsub.publish(\"closequerymenu\", obj); vue"_李公子丶的博客-程序员宅基地

消息订阅与发布(pubsub) 一种组件间通信的方式,适用于任意组件间通信。 使用步骤: 安装pubsub:npm i pubsub-js 引入:import pubsub from 'pubsub-js' 接收数据:A组件想接收数据,则在A组件中订阅消息,订阅的回调留在A组件自身。 methods(){ demo(data){......} } ...... mounted() { this.pid = pubsub.subsc._"pubsub.publish(\"closequerymenu\", obj); vue"

第十五周oj题目输出特定的字符串-程序员宅基地

作者:夏晓林时间:2016.12题目描述:输出n个字符串,把其中以包含字母B或b的字符串输出。输入:第一行 n 第二行到第n+1行,每行一个字符串输出:包含字母B或b的字符串问题及代码:#include int main(){ int i,j,n,a; char str[80]; scanf("%d",&n);

访问FTP服务器的四种方式_ftp://127.0.0.1:5050-程序员宅基地

访问FTP服务器的几种方式:1.客户端软件2.浏览器3.资源管理器4.命令行_ftp://127.0.0.1:5050

使用Javamail发送邮件例子 eclipse_eclipse写邮件发送-程序员宅基地

1.第一步,下载jar包(我用的是Eclipse【dom4j-1.6.1.jar,jaxen-full.jar,mail.jar,pop3.jar,saxpath.jar,smtp.jar】,如果用的MyEclipse的话(javaee6)必须导入【dom4j-1.6.1.jar,jaxen-full.jar,saxpath.jar】)2.将jar包导入Eclipse的lib目录下3._eclipse写邮件发送

卷积核操作、feature map的含义以及数据是如何被输入到神经网络中_卷积的feature map-程序员宅基地

一、卷积核的定义 下图显示了CNN中最重要的部分,这部分称之为卷积核(kernel)或过滤器(filter)或内核(kernel)。因为TensorFlow官方文档中将这个结构称之为过滤器(filter),故在本文中将统称这个结构为过滤器。如下图1所示,过滤器可以将当前层网络上的一个子节点矩阵转化为下一层神经网络上的一个单位节点矩阵。单位节点矩阵指的是高和宽都是1,但深度(长)不限的节点矩阵。 ..._卷积的feature map

Docker 镜像构建的时候,应该小心的坑-程序员宅基地

不要改文件如果run了以后,你还需要进入到容器中,修改容器的配置,那么,这个容器是危险的。一旦容器无法启动,就再也改不了配置。那么你就需要删除和重新run这个容器,而配置要再改一遍。一个可用的镜像在发布后应该无需修改任何参数。关于这一点也有点争议,但是根据 Docker 容器创建的初衷,我认为修改以及启动的容器,是非常不好的。新版本的docker 通过docker exec 给了一个后悔药,然..._docker 推镜像老是被系统杀死