Server中的数据类型,2008从入门到精通

参考 SQL Server 2012编程入门经典(第4版)

SQL Server 自带的数据类型

 

 

 

 

 

转自:http://www.maomao365.com/?p=4390

目录

整型:

 图片 1

 

 

一、coalesce函数简介

  • 1.触发器
    • 1.1.DDL触发器
    • 1.2.DML触发器
    • 1.3.创建触发器
      • 1.3.1.创建DML触发器
      • 1.3.2.创建DDL触发器
      • 1.3.3.嵌套触发器
      • 1.3.4.递归触发器
    • 1.4.管理触发器

货币

图片 2

 

coalesce 系统函数,比ISNULL更强大,更方便的系统函数,
coalesce可以接收多个参数,返回最左边不为NULL的参数,当所有参数都为空时,则返回NULL
coalesce是最优isnull写法解决方案
以前我们使用isnull对两列或多列数据进行为空返回时候,需要多次使用isnull函数
—————————————————————————-
例:
declare @a varchar(10),@b varchar(10),@c varchar(10)
当@a为null时,我们查看@b是否为NULL,不为null,则返回@b ,否则查看@c 不为NULL,则返回@c ,否则返回NULL

1.触发器

触发器是一种特殊的存储过程,与表紧密关联。

近似小数

  图片 3

 

select isnull(@a,isnull(@b,isnull(@c,null)))
/*当需判断的参数越多时,我们的函数表达式就会变的异常复杂*/

1.1.DDL触发器

当服务器或数据库中发生数据定义语言(DDL)事件时将被调用。如CREATE,ALTERDROP等操作。如果要执行以下操作,可以使用DDL触发器:

  • 防止对数据库架构进行更改
  • 希望数据库中发生某些情况以响应数据库架构中的更改
  • 要记录数据库架构中的更改或事件

日期/时间

但我们使用coalesce函数,会使此 表达式变的优美,通俗易懂
select coalesce(@a,@b,@c)
——————————————————————————–

1.2.DML触发器

当数据库服务器中发生数据操作语言(DML)事件时将被调用。如INSERT,DELETE,UPDATE等操作。将DML触发器和触发语句作为可在触发器内回滚的单个事务对待,如果检测到错误,则整个事务回滚。DML触发器在一下方面非常有用:

  • 可实现数据库相关表之间的级联更改
  • 可以防止恶意或错误的DML语句事件,并强制执行比CHECK约束更为复杂的其他限制
  • 可以评估数据修改前后表的状态,并根据该差异采取措施

一个表中的多个同类DML触发器,允许用多个不同的操作来响应同一个修改语句
SQL Server 2008为每个触发器创建了2个特殊的表:INSERTED表和DELETED表。这是两个逻辑表,由系统来创建和维护,用户不能对他们进行修改。它们存放在内存中,而不是在数据库中,并且结构与被DML触发器作用的表的结构相同。
INSERTED表中存放了由执行INSERTUPDATE语句而插入的所有行,在执行INSERTUPDATE语句时,新的行将同时被插入到触发器作用的表和INSERTED表中。INSERTED表中的行是触发器作用的表中行的副本。
DELETED表中存放了由执行DELETEUPDATE语句而删除的所有行,在执行DELETEUPDATE语句时,被删除的行将由触发器作用的表中被移动到DELETED表,两个表中不会有重复行。

 

图片 4

 


1.3.创建触发器

 特殊数字

图片 5

图片 6

 

二、coalesce 应用举例

1.3.1.创建DML触发器

 字符

图片 7

图片 8

 

 

1.3.1.1.INSERT触发器

示例1:创建一个触发器Automatic_division,当在Student表中插入一条学生信息时,触发器根据入学分数(stu_enter_score)对学生进行自动分班,并在class_student表中插入一条记录。
分班要求:
|Stu_enter_score |Class_id |Class_name|
|-------------------|------------------|--------------|
|stu_enter_score>=700| 01| 创新A班|
|650<=Stu_enter_score<700| 02| 重点B班|
|600<=Stu_enter_score<650| 03| 提高C班|
|550<=Stu_enter_score<600| 04| 普通D班|
|500<=Stu_enter_score<550| 05| 普通E班|
|Stu_enter_score<500| 06| 普通F班|
执行下列语句

CREATE TRIGGER automatic_division
ON student--新建一个检测student表的触发器,命名automatic_division
FOR INSERT--检测到INSERT操作时触发器工作
AS
DECLARE @score INT,@stu_no VARCHAR(8),@class_id CHAR(2)
--声明三个变量
DECLARE stu_cursor CURSOR LOCAL FORWARD_ONLY--声明一个指向inserted表的局部游标stu_cursor
FOR SELECT stu_no,stu_enter_score FROM inserted
OPEN stu_cursor--打开游标
FETCH NEXT FROM stu_cursor INTO @stu_no,@score--将游标指向inserted表的第一个数据并把游标指向的stu_no和stu_enter_score值分别赋值给@stu_no和@score
WHILE @@FETCH_STATUS=0--开始循环
BEGIN
BEGIN--先对@score的数值范围做判断,以确定该学生的班级编号
IF @score>=700
SET @class_id='01'
ELSE IF @score<700 AND @score>=650
SET @class_id='02'
ELSE IF @score<650 AND @score>=600
SET @class_id='03'
ELSE IF @score<600 AND @score>=550
SET @class_id='04'
ELSE IF @score<550 AND @score>=500
SET @class_id='05'
ELSE
SET @class_id='06'
END
--判断结束
INSERT INTO class_student(class_id,stu_no)
VALUES(@class_id,@stu_no)--将数据插入到class_student表中
FETCH NEXT FROM stu_cursor INTO @stu_no,@score--将游标移向inserted表的下一个数据,重复这个循环
END--循环结束
CLOSE stu_cursor--关闭游标
DEALLOCATE stu_cursor--释放游标资源
GO

验证代码是否正确
student表中插入数据,并查看class_student表中的数据是否正确

INSERT INTO student(stu_no,stu_name,stu_sex,stu_enter_score)
VALUES('20180001','邹莉莉','女','389'),
('20180002','万兴','男','701'),
('20180003','孙伟','男','652'),
('20180004','温佳静','女','676'),
('20180005','姜立夫','男','542')

Class_student表中的数据如图所示
图片 9
游标示例2:对student表中还未分班的学生进行分班
Student表中的数据如图所示
图片 10
其中stu_no20180001~20180005的学生已经在示例1中分班,剩下的学生全都未分班。
执行下列语句

ALTER TABLE student
ADD stu_division_state bit--为student表新建一列记录是否已分班,true表示已分班
GO
DECLARE stu_class_cursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT stu_no FROM class_student
--新建游标stu_class_cursor指向class_student表的所有数据
OPEN stu_class_cursor--打开游标
DECLARE @stu_no VARCHAR(8)
FETCH NEXT FROM stu_class_cursor INTO @stu_no
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE student
SET stu_division_state=1
WHERE stu_no=@stu_no
FETCH NEXT FROM stu_class_cursor INTO @stu_no
END
CLOSE stu_class_cursor--关闭游标
DEALLOCATE stu_class_cursor--释放游标资源
---所有学生是否分班已经全部记录在stu_division_state中
GO
DECLARE @stu_no VARCHAR(8),@score INT,@class_id CHAR(2)
DECLARE stu_cursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT stu_no,stu_enter_score FROM student WHERE stu_division_state IS NULL
--新建student表的游标stu_cursor,指向所有未分班学生
OPEN stu_cursor--打开游标
FETCH NEXT FROM stu_cursor INTO @stu_no,@score
WHILE @@FETCH_STATUS=0--循环开始
BEGIN
BEGIN--先对@score的数值范围做判断,以确定该学生的班级编号
IF @score>=700
SET @class_id='01'
ELSE IF @score<700 AND @score>=650
SET @class_id='02'
ELSE IF @score<650 AND @score>=600
SET @class_id='03'
ELSE IF @score<600 AND @score>=550
SET @class_id='04'
ELSE IF @score<550 AND @score>=500
SET @class_id='05'
ELSE
SET @class_id='06'
END
INSERT INTO class_student(class_id,stu_no)
VALUES(@class_id,@stu_no)--将数据插入到class_student表中
UPDATE student--将student表的stu_division_state改成已分班
SET stu_division_state=1
WHERE stu_no=@stu_no
FETCH NEXT FROM stu_cursor INTO @stu_no,@score--将游标移向inserted表的下一个数据,重复这个循环
END--循环结束
CLOSE stu_cursor
DEALLOCATE stu_cursor
GO

结果如图所示
Student表的数据
图片 11
Class_student表的数据
图片 12
至此Student表中所有学生都已分班
为了以后方便,可以将游标示例2中的代码稍作修改封装成一个用户自定义存储过程
存储过程示例3
修改后的代码如下

CREATE PROCEDURE student_division
AS
BEGIN
UPDATE student
SET stu_division_state=0--先将student表中所有学生的分班情况都标成未分班

DECLARE stu_class_cursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT stu_no FROM class_student
--新建游标stu_class_cursor指向class_student表的所有数据
OPEN stu_class_cursor--打开游标
DECLARE @stu_no VARCHAR(8)
FETCH NEXT FROM stu_class_cursor INTO @stu_no
WHILE @@FETCH_STATUS=0
BEGIN
UPDATE student
SET stu_division_state=1
WHERE stu_no=@stu_no--利用游标找出student表中已分班的学生并标记分班状态
FETCH NEXT FROM stu_class_cursor INTO @stu_no
END
CLOSE stu_class_cursor--关闭游标
DEALLOCATE stu_class_cursor--释放游标资源
---所有学生是否分班已经全部记录在stu_division_state中

DECLARE @score INT,@class_id CHAR(2)
DECLARE stu_cursor CURSOR LOCAL FORWARD_ONLY
FOR SELECT stu_no,stu_enter_score FROM student WHERE stu_division_state=0
--新建student表的游标stu_cursor,指向所有未分班学生
OPEN stu_cursor--打开游标
FETCH NEXT FROM stu_cursor INTO @stu_no,@score
WHILE @@FETCH_STATUS=0--循环开始
BEGIN
BEGIN--先对@score的数值范围做判断,以确定该学生的班级编号
IF @score>=700
SET @class_id='01'
ELSE IF @score<700 AND @score>=650
SET @class_id='02'
ELSE IF @score<650 AND @score>=600
SET @class_id='03'
ELSE IF @score<600 AND @score>=550
SET @class_id='04'
ELSE IF @score<550 AND @score>=500
SET @class_id='05'
ELSE
SET @class_id='06'
END
INSERT INTO class_student(class_id,stu_no)
VALUES(@class_id,@stu_no)--将数据插入到class_student表中
UPDATE student--将student表的stu_division_state改成已分班
SET stu_division_state=1
WHERE stu_no=@stu_no
FETCH NEXT FROM stu_cursor INTO @stu_no,@score--将游标移向inserted表的下一个数据,重复这个循环
END--循环结束
CLOSE stu_cursor
DEALLOCATE stu_cursor
END
GO

注:和游标示例2的代码相比,示例3的代码添加了将所有学生分班状态标记为0的过程,去掉了添加stu_division_state列的过程,但对原来已有的学生的分班状态赋值这个步骤并未删去,而是进行重复校验。并且删除了两段代码中的GO和第二段用于给学生分班的代码中对@stu_no变量的重复声明。

student表插入数据并运行student_division的存储过程

注:对student表插入数据前应先禁用示例1的触发器automatic_division

执行下列语句

ALTER TABLE student DISABLE TRIGGER automatic_division
--禁用automatic_division触发器
INSERT INTO student(stu_no,stu_name,stu_sex,stu_enter_score,stu_division_state)
VALUES('20180006','王洋','男','724',NULL),
('20180007','易阳','男','713',NULL),
('20180008','孙浩','男','584',NULL),
('20180009','张秋燕','女','420','False'),
('20180010','胡燕','女','527','True')

Student表的数据如图所示,红框内就是我刚刚插入还未分班的数据,其中2018000920180010这两个学生的分班状态被我误标成FalseTrue
图片 13
执行存储过程

EXEC dbo.student_division

结果如图所示
Student表的数据(分班状态都为true了)
图片 14
Class_student表的数据
图片 15

本文由ca88手机版登录发布于亚洲城ca88手机版官网,转载请注明出处:Server中的数据类型,2008从入门到精通

TAG标签: ca88手机版登录
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。