SQL基础教程

数据库的工作原理及概念

一、 启动安装SQL server没得说,有点电脑知识的都会,这里就不再详细解释了。

关于win7的安装仔细看一下连接http://www.cnblogs.com/icewee/articles/2019783.html

二、 信息是对各种事物的存在方式,运动状态和互相联系特征的一种表达和陈述。

数据是描述符号的记录,是信息的载体,是信息的具体表达形式,。

数据处理是将数据转化为信息,如对数据的分类,组织,编码,储存,查询,维护,加工,计算,传播,以及打印。 数据管理是指数据的收集,整理,组织储存和查询等操作。

数据库技术有三个管理阶段

1,人工管理阶段,

2,文件系统阶段,

3,数据库系统阶段,

主要记数据库管理阶段 优点: 数据库结构化,(简而回答就是由MSDN管理数据库,减少冗余,数据共享,一个数据可以在多个应用程序中使用,) 较高的数据共享性,(数据库将对整个系统起作用,不像人工管理,一组数据对应一个程序,最大好处减少冗余。) 较高的独立性,(与应用程序相互独立,物理独立,逻辑独立,(数据定义修改,联系变更,不影响程序))

由DBMS统一管理,(作用数据共享并发,可以同时存取统一数据,而不会发生冲突,) DBMS:是广泛的数据库管理系统,作用,1,安全保密,防止非法获取,2,完整性保护,正确性,有效性,相容性,主要目的并发存取的时侯,对多用户操作加以控制协调,3,在数据破坏是进行恢复。

数据库管理的结构图:

数据库→DBMS→程序1,程序2,程序3

数据库

是指长期存在计算机内的,有组织,可共享的数据集合,简而答之就是一个数据堆,记录着许多个人信息或者什么的,但是排列有序,冗余较小,

DBMS对其管理,也是应用程序后台的存取库,以文件形式存在计算机上,是数据库系统的操作对象,

数据据库管理系统:

建立使用围护。替应用程序访问数据库,创建,查询更新插入修改,检索,维护工作,保证数据库的安全完整,

数据库应用系统:

凡是使用数据库技术管理,都称为数据库应用系统

数据库用户称为三种:

1终端:使用软件的普通用户,看不要数据库的内部,

2应用程序员:对数据库结构设计。分析,开发,维护,设计数据库系统中的各类程序。

3数据库管理员:最高级的用户,设计定义数据库系统,监督和控制数据库系统的使用和运行,改进和重组数据库系统,优化性能,定义数据的安全和完整性约束,备份与恢复数据库。

数据库管理系统的功能:

数据定义与操纵,数据库运行控制,数据库组织存储管理,建立维护数据库,

数据库通信接口:

提供与其他软件进行通信的功能,联机处理接口,远程作业输入接口。

三级模式:

内模式,是物理模式,物理存储状态,一个数据库只有一个内模式。 模式:逻辑i模式,对数据库中全部数据的逻辑结构和特征进行描述,是所有用户的公共视图,数据库管理系统提供模式描述语言来定义模式,一个数据库只有一个模式,。 外模式:数据库用户都能够看见的,是局部数据的逻辑结构和特征的描述,一个数据库可以有多个外模式,一个应用程序只能使用一个外模式,

二级映像:

外模式/模式:当模式改变外模式不必一起改动,仅仅改动映像。 模式/内模式:可以保证物理数据的独立性(模式改变内模式不必改变)

数据库的发展:

分布式数据库http://baike.baidu.com/view/68389.htm

面向对象数据库http://baike.baidu.com/view/682410.htm

多媒体数据库http://baike.baidu.com/view/297200.htm

数据仓库http://baike.baidu.com/view/19711.htm

数据模型

信息存在的三种状态(三种世界)

现实世界:顾名思义,就是现实眼睛看到的世界,客观世界。实体!想要了解的可以看《当下的力量》这类哲学书籍

信息世界:第一章提到的概念,就是大脑所想象到的模型,抽象的。

数据世界:这章的重点要了解的,就是计算机的天下,计算机的世界。全部都是数据,(其实一开始都是由01010000101001这样的字符组成,)是信息世界中信息变成数据的产物。数据世界具有量化(把图像样本连续变化的模拟量或密度值转换成离散数字量样本值的过程。),物化(实物化)在数据世界都是以数据模型描述事物!

概念模型

根据自己的观点想象的,(提到N遍了。。)

1实体:客观存在的东西!

2属性:就是对实体进行详细的解释,一个实体可以有多个属性,但是只能有一个码(码就是能够唯一认可这个实体的东西,就是看到这个码就可以知道是那个实体。在后面会有提到表的主键和外键,主键就是一个码,当然主键可能是由多个属性拼接而成,也可以是一个属性。)

3码:上面已经提到,要注意的是一个表,一个实体里面可以有多个码,但不是多个主键,主键是码,但是码不是主键,当作主键的码称之为主码,其他称之为候选吗

4实体型:用实体的名字和属性的名字集合来刻画的同一个类的实体,就是一个实体模块。

例如:“学生(姓名,学号,性别)”类似于后面的一个表。

5实体集;没有必要特别的解释,就是好多一样实体型的集合。例如全体学生(简单的东西无可解释)

6联系:

就是找到一个属性,必定可以在这个属性的基础上联想到另外的一个或者几个属性,分为三种,

一对一联系 一个部门只有一个经理

一对多联系 一个老师教多个学生

多对多联系 一个学生选多门课,一门课有多个学生选。

(联系就是联系,就是有联系,有关系,好像你爸爸跟你有关系。。哪那么多解释!)

实体-联系模型

简称为E-R模型

img

来张图片,其他不解释了。自己看书!

它与计算机和DBMS无关,只是人们为了方便理解画得图,最重要转化为数据模型

数据模型

根据计算机的系统观点进行建模。(在这里解释一下数学建模,就是将现实中的事件转化为数学公式模块进行处理,与我们计算机行业相类似,都是将现实问题转化为另一种形式进行简单的处理,在编程语言中是将某个问题编制成一个个函数,随时调用,方便简洁!)

是严格定义概念的集合,表述了系统的静态特征,动态特征和完整性约束条件

由数据结构,数据操作,数据完整性约束组成,

数据结构

对数据库静态特征的描述(对数据的物理排列,框架(结构架子)等等描述),研究的对象是数据库的组成部分,在数据库系统添加数据模型的时候要根据数据结构的定义添加,比如增次结构就依照层次的类型添加。暂时分为3个模型

1层次模型

解释:

就是树状的层次结构,img如图所示,每个结点表示一个记录类型(就是一个类型,如学校)每个线段表示一个联系(就是两个类型的关系)只有一个结点没有双亲结点(双亲结点就是父结点,就是上级的枝杈)。称之为根节点。

根节点以外的其他节点有且只有一个双亲结点,上级与下级之间是一对一的联系。最后的结点称之为叶。

可以进行查询,删除,更新,插入

查询必须通过双亲结点,

删除一个类型的时候其下面的子分类将会全部删除,

更新的时候要保持下面子女节点的一致。

插入的时候必须有双亲结点可以插入(比如要插入在数计系的一个学生,但是没有数计系,就不能插入)

利:方便,联系固定,容易实现

弊:插入删除麻烦,不能直接显示多对多联系,查询要通过双亲结点。

2网状模型

解释:允许一个结点有多个双亲结点,允许多个结点没有双亲结点,

img

插入允许插入尚未确定双亲结点值的子女结点值。

删除允许只删除双亲结点值,

只更新指定记录即可。

查询可以有多种路径,不必要通过某一个双亲结点。

3关系数据模型

解释:用二维表格表示实体与实体之间的数据模型称之为关系模型。

关系:一个关系就是一个表。

元组:一行称之为一个元组。

属性:前面已经介绍过,这里每一个列称之为一个属性,

域:就是属性的取值范围,当给属性创建约束的时候它的域相对就发生了变化

关系模式:与之前的实体型差不多,一个表名(属性1,属性2)

关键字和码:不用解释,确定唯一元组的属性

候选关键字和候选码:简而答之就是另外的关键字,但是不叫关键字,也能标识元组

主键,主码:许多关键字中指定的一个或者一组属性

主属性,非主属性:关键字就是主属性,不包含任意候选码的属性就是非主属性

外键或外码:在这个表里面不是主属性,而在另外一个表里面却是主属性,则称之这个属性是这个关系的外码(我这里说的表,关系,都是一样的)

例:创建外码: alter table 表

​ Add constraint 约束名 foreign key (属性1) reference 表2(属性1)

将表中的属性1设置成了外键,这个外键在表2中是主键。

层次模型和网状模型称为非关系模型

数据操作:

顾名思义,对数据进行删除,插入,修改,检索,更新,对数据库进行动态变化,其中检索查询是用的最多的

数据模型要定义操作的确切含义,操作符号,操作规则,现实操作语言。。。

数据的完整性约束:

对数据的某些值项的约束,关于数据状态和状态变化的约束集合,保证数据的正确有效一致。例如以后会提到unique(唯一)约束,primary key(主键)约束,foreign key (外键)check(检查) default(默认)约束都是完整性的约束,以后会举例如何应用这些约束。

关系数据库

关系数据库就是一张二维表(一列一列的表),表格里面各个数据都互相有关系,称之为关系数据库,但是二维表不一定是关系数据库。

关系的约束:

每一列的数据类型相同,满足同一个约束条件。

各列属性的名称不能重合,数据类型可以相同。

任意两行(元组)不能完全相同

列的排列次序部分先后。(学号在第一列还是姓名在第一列,但是在使用 insert into(列名1,列名2) values(数据1,数据2)插入数据的时候列明其实可以不填写的,不填写的话要注意排列的次序。否则会出错的)

元组的位置不分先后。

每个属性必须是单一的类型。(不能够在班级属性再分下级属性,关系结构不能够嵌套。)

关系模式:

关系是关系模式中的一个存在的状态或者内容。

关系模式是型,关系是他的内容,关系模式是静态的关系是动态的

关系模式和关系统称为关系(就是那个二维表。关系模式可以说是表的框架,关系是表的内容)

关系模式是一个五元组(就是五个元素组合)

R(U,D,dom,F)

R 关系的名称

U 属性的集合

D 属性的域

dom 属性向域的映像集合。

F属性间的互相依赖集合。

关系数据库:

采用关系模型的数据库

关系数据库有型和值的区别,

型:若干个关系模型框架。

值:在某一时刻对应关系的集合。

关系的完整性:

实体完整性

主码不能出现空值

参照完整性

简而答之就是,若AB是通过外键连接的,A的外码R必须是空值或者B中存在的值,

用户自定义完整性

就是自己对表中属性的约束条件,必须遵循,否则会出错。

关系运算:

传统的集合造作:并,差,交,笛卡尔积

专门的关系元算:投影,选择,连接,除法(笛卡尔积的逆运算)

比较运算:大于,小于。。。

逻辑运算:与或非。。

后面进行详细的解释。

传统的集合运算:

1笛卡尔积 最大限度的元组集合,用R的第一个元组与S 的每一个元组进行联合。得到完整的关系,组合成一个表。(可以是两个不同的关系模型)

2并 具有相同关系模型的,进行并操作,取所有元组集合。然后删掉相同的元组

3差 R和S两个关系,并且关系模式相同,R-S是属于R但是不属于S 的集合关系。

4交 既属于R又属于S的集合

专门的关系运算:

1选择

选择满足指定条件的元组,(类似于后面的查询功能)

2投影

选取出几个列,删除相同的元组,因为当删除掉几列之后,会有以前两个元组只有一列中的数据不同,而删除掉那一列之后便会出现相同的元组,然而根据关系的基本约束条件不能有相同的元组,所以会被自动的略除

3连接

在对两个表进行连接的时候早注意的是只有当两个表中有相同的列的时候才可以连接。

连接运算过程

确定属性列

确定参与比较的属性列

逐一选取R中的元组与S中与其符合比较关系的元组进行拼接

小于连接

在笛卡尔积的条件下取满足连接条件的值

等值连接

与小于连接含义相同,只是必须取两个相等的数值的元组

自然连接

把有重复的属性去掉,如两个表都有学号属性则在连接之后就会去掉一个学号属性,最后的连接结果不会减少,但是行数列数却减少了,减少冗余。 也是等值连接,只是将相同的属性进行等值连接。

关系规范化基础

数据依赖:

函数依赖

多值依赖

连接依赖

主要说明函数依赖:也是本章的重点 定义: 如果对于属性x每一个值都有一个Y与之相对应。例如:每一个学号都有一个成绩与它相对应,则Y函数依赖于X。就是说X的值决定Y的值,X不可以重复,Y可以重复。

非平凡函数依赖和平凡函数依赖:

如果X→Y且Y属于X。就是说X是两个属性的集合,而Y是其中的一个属性。则称之为平凡函数依赖。

如果X→Y且Y不属于X,则称之为非平凡函数依赖。

完全函数依赖和部分函数依赖:

就是说如果X→Y的时候如果有个一Z也属于X,并且Z→Y也成立则称之为部分函数依赖。

X→Y并且如果任意一个属于X的属性集合Z都不能满足Z→Y的话那么称之为完全函数依赖。

传递函数依赖:

如果X→Y成立Y→Z成立,并且不可以逆向传递,就是说Y→X成立。那么就称之为传递函数依赖。

码的函数依赖表示 若K→U(全部属性)则称之K为R上的候选码(其中一个是主码)

外码:如同外键,不再解释

关系规范化:

目的: 解决关系模式中存在的数据冗余,插入和删除异常,更新异常。

基本思想是消除数据依赖中的不适合的部分,使各个关系模式达到某种程度的分离,使一个关系描述一个概念,实体,或者实体之间的关系。

一共有六种范式,在此介绍三种范式以及BC范式。

第一范式

就是没有重复的列,重复的属性。并且每一个属性都是不可以再次进行分解的。

第二范式

非主属性完全依赖与主关键字。并且在满足第一范式的基础之上。

第三范式

没有传递依赖与码的非主属性,就是说不能有非主属性依赖于其他非主属性。并且在第二范式的基础上。

BC范式

对于任何非平凡函数依赖X→Y,X均包含码。 就是说在第二范式的基础上,所有的非主属性都完全依赖于每个候选码,不能依赖于一个非主属性的集合,或者非主属性。主属性完全依赖于每个不包含它的候选码。

数据库和表

本章和第九章乃是重中之重!

前面的567章就不再讲解,

需要注意的是第五章将E-R模型转化为关系模式。

其实倒也是不难,只是可能会在试题中出现。

关系模式结构

学生(学号,姓名,出生日期,所在系,年纪,平均成绩)

第六章不用讲解。

第七章的内容在第八章和第九章里面会完全的体现出来。这里不再讲解。

下面讲解正题:

创建一个数据库

数据库是由

主数据文件 后戳文件名 mdf 数据库必须有主数据文件,且只有一个

辅助数据文件 后戳文件名 ndf 没必要有,也可以有多个

事务日志文件 后戳文件名 ldf 恢复数据库文件的日志文件,可以有多个,至少有一个,

可以有多个。

Server 2005不强制使用这样的后戳名字,只是起到了标识的作用

数据库文件组:

多个数据库文件组成的一个整体

主文件组

包含系统表,主要的数据库文件,没有指派给其他文件组的其他文件。

1、创建主文件组的时候可以利用代码语句“create database 文件组名”这是创建最简单的数据库文件组img(其实就是创建了一个数据库),不用设定任何条件,全部取默认值,

(自动创建一个日志文件大小为1/4大小总数据文件。

并且日志文件的文件名和数据库名默认相同。

只是后戳不同。自动设置名字name为“数据库名_data”。

自动设置默认路径名filename。

自动设置初始大小size与模版数据库中主文件大小size一致。

其他数据文件为默认1MB,最小是512KB。

文件最大可增长到的尺寸MAXSIZE是默认充满磁盘。

默认每次增加的大小FILEGOWTH的值是10%,每次扩展最小值是64KB,增长可以按照百分比或者大小进行设定。)

2、使用ALTER database可以更改数据库中的属性。

例:

1
2


1
2
3
4
5
6
7
8
9
 ALTER database

Modify file

(name =’逻辑文件名’, //必须填写逻辑文件名

Size= 文件大小,

Maxsize=增长限制)

3、使用file group 创建文件组。

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
create database 数据库2

On primary --主文件组

(name='数据库',

filename='F:\临时\数据库.mdf'

), --有个逗号,在与日志文件中间不必添加逗号。但是两个日志文件中间需要添加逗号。

Filegroup fg1 --定义一个文件组 grope就是组的意思,多简单。。所以外语好的人可别浪费了

(

name='数据库名',

filename='F:\临时\数据库名.ndf' --与创建数据库填写的属性相同。

)

--alter database 数据库

--add

Log on --file

(

name='数据库名',

filename='F:\临时\数据库名.ldf')

(说明:这个–是标注,后面的在SQL中不会运行。)

文件组不能独立于数据库文件创建。文件组是在数据库中对文件进行分组的一种管理机制。数据实际上是依附于表来存在的,我们将表放入到文件组中,而文件组是一个逻辑的概念,其实体是辅助数据库文件(.ndf),所以就等于将我们指定的数据放入到了指定的辅助数据库文件中,然后如果将这些辅助数据库文件放入在不同的磁盘分区中,就可以最终实现有针对性的对相应的数据实现性能的优化。

这样就创建了一个名字是“数据库2”的一个数据库,包含有日志文件,主数据文件,文件组。

下面也可以通过修改表添加一个文件组文件。

1
2


1
2
3
4
5
6
7
8
9
alter database 数据库2

add file

(name='文件组',

filename='F:\临时\文件组.ndf'

) to filegroup fg1

可以增加文件组文件到“数据库2” img

修改数据库:

增加数据库空间

1
2


1
2
3
4
5
6
7
ALTER database
Modify file //修改文件属性
(name =’逻辑文件名’, //必须填写逻辑文件名

Size= 文件大小,

Maxsize=增长限制)

减小数据库文件大小

数据库名字上面右击选择,任务,收缩,文件选项。

出现收缩数据库对话框,保持默认设置,确定,收缩完毕。

收缩特定的数据文件,日志文件,任务,收缩,文件选项。

自动收缩可以在选项页面设置,

(不会小于初始的大小)

删除数据库文件

Alter dababase 数据库名

Remove file 逻辑文件名

数据库更名

Sp_renamedb ‘原数据库名’,’现数据库名’

删除数据库

Drop database 数据库名

对于数据库的建立操作还是相对简单的,毕竟没有什么深奥的。只有一些简单的创建修改死固定格式而已。这一章先写一半发表出去,创建修改表相对要复杂一点。

表的操作

创建一个表

在SQL中创建一个表其实简单的很,并且这个表与EXCEL的表基本相同(这样大家不至于畏惧SQL,其实它并不难,甚至比C++要简单的多。),并且可以说是就是同样的表,因为在SQL中可以将SQL创建的表导出成EXCLE表格,并且可以将EXCLE表格导入SQL中进行操作,不同的只是SQL相对较为复杂,并且功能较多(是非常多)。

使用management studio 视图创建表就不再详细讲解了,简单的很,主要说明使用SQL语句进行创建表

创建表的时候可以使用create table 表名 创建表

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
use 数据库 

go

create table XSS

(学号 char (12) ,

姓名 char(8),

性别 char(2)

)

在创建表的前面可以添加 “use 数据库的名字”便可以转到指定的数据库,这这个数据库里面创建表。img这里创建的表的列没有任何约束,例如主键约束primary key 默认约束 default ‘默认约束值’ not null 也是一种约束,不允许空值的约束。

在创建表的时候只要在列明的最后面天上SQL语句就可以了,也可以在创建表之后再添加约束

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
use 数据库

go

Alter table XSS

add constraint X_M check (性别='男' and 姓名='女') --增加约束,中间是约束名X_M(约束名的起名方式自定义,一般写约束列的首字母+约束名的首字母) check是选择约束(在括号里面的内容选择)

命令已成功完成。

create table XSS

(学号 char (12) primary key,

姓名 char(8),

性别 char(2)

)

命令已成功完成。

删除表的时候可以使用 drop table XSS 简单快捷

修改表

修改表只需要alter table 表名 即可以修改,下面详细介绍

修改列的属性

1
2


1
2
3
Alter table xss

Alter column 姓名varchar(50) null --将列的数据类型改为了varchar型,就是可以自动变动所占内存大小的char字符型。适用于设定不定字数的列,比如备注列。

添加字段

1
2


1
2
3
4
5
6
7
Alter table XSS

Add 出生日期 smalldatetime null --small 低精度的时间

constraint fg --约束+约束名

default getdate() --默认约束为系统当前时间

删除一列的数据

1
2


1
update 表名 set 列名 = ''

删除一列

1
2


1
2
alter table XSS
drop column 出生日期

列约束和表约束

本章主要讲的几个约束有主键约束,primary key 外键约束 foreign key 唯一性约束 unique 检查约束 check 默认值约束 default

创建主键约束的几种方式:

直接在创建表的一列后面添加约束,

例:

1
2


1
2
3
4
5
6
7
Create table asd

(学号 char primary key,

姓名 char

)

这样的命令式成功的,注意在这里我没有对char设定它的大小系统将会自动设置为char(1)的大小。如果设定的是varchar不设定所占字节的话,系统将设定为1,并且自动增长的时候不会超过所设的字节。例如varchar(10)就不会超过10。

还有一种对于主键可以设置表级约束,就是当一个表里面需要两个主键的时候,可以这样设定

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
Create table sdf

(姓名char ,

班级char ,

年龄char,

成绩char

Primary key (姓名,班级)

)

这样的命令也是成功的,要注意的是在这里最后一行本应当写成“constraint PK_XB Primary key (姓名,班级)”然而我并没有这样写,我是想证明这样写也是正确的,但是,这样的话对于constraint约束的名字将会系统自动取值。下面我执行

1
2


1
sp_helpconstraint sdf

这样的命令来查询 sdf表里面的约束

出现了约束名PKsdf03317E3D

img

如图所示,这就是没有定义约束名的后果,主要体现在当需要删除某个约束的时候,你不知道约束名,也就变的异常的复杂。删除约束的语法后面会提到。

还有一种就是使用alter table 添加约束

先讲一下格式

Alter table 表名 –修改一个表

Add [constraint 约束名] –增加约束,[]这个括号里面的内容可以不填写,上面已经提到过,不再解释。

Primary key –增加的是个主键

Clustered|nonclustered –这里可以选填聚集或者非聚集索引,如果添加的是聚集索引,那么将不能再设置其他聚集索引(如果不是主键的设置了聚集索引,那么将不能再设置主键。),因为主键本身就是聚集索引,而一个表里面只能由一个聚集索引。

(column[,……n]) –这里是确定有几个列要设置主键约束。

例:

1
2


1
2
3
Alter table sdf 

Add constraint PK_xm primary key (姓名)

命令是成功的。

删除约束

alter table sdf

drop constraint 约束名

利用modify可以改变一列的数据格式

alter table XSS

modify 学号 int 将列明改为 int的数据类型

创建删除unique约束

Unique是对列约束成唯一值的约束。类似于候选主键,也是一般对候选主键的约束。

1, 在创建标的时候设定唯一性约束。

直接在列名后面添加constraint UK_xs unique

2,利用修改表创建unique约束,

Alter table xss

Add unique (姓名)

命令已成功完成。

删除约束同主键约束相同

创建删除foreign key 约束

可以是实现表和表直接的联系,在创建视图的时候可以体现出来,插入数据的时候也会因为有外键约束而可能插入不成功

依然有两种创建方法

1, 创建表的时候在后面添加约束

格式: 学生号 char (12) Constraint XS_CH foreign key references 主表(学生号)

2, 在修改表中添加

Alter table 选课

Add constraint foreign key(学生号) references 学生(学生号)

创建删除check约束

与上面类似,

Constraint ck_sj check(价格<50)

或者

Alter table xss

Add constraint ck_sj check (成绩<100 and="" 成绩="">0)

删除与之前相同

创建删除default约束

在后面直接填上 default 默认值 即可

例如

Alter table xss

Add Constraint df_xb default ‘男’

书上所说的 getdate()是系统当前时间。后面会详细提到。

要注意的是设置默认值的时候要记得所设置的数据格式与原来的数据格式要相同,并且在插入数据的时候如果设置了默认值那么插入数据要将所插入的那个数据写成default 或者

inster into (在这里面不写所设定默认值的列) values (数据,数据 )

表的数据操作

插入数据

Inster into (列名) valuse(数据,数据)

修改数据类型

利用modify可以改变一列的数据格式

alter table XSS

modify 学号 int 将列名改为 int的数据类型

删除表里的行

Delete 表名 where 列名 in (数据) –也可以用not in (某一列),在这里删除满足条件的行

这里可以限制where 列名 btween 数据 and 数据 可以取两个数据之间的所有行

很灵活的

删除全部内容而不删除表

Delete from 表名

删除某一列

Alter table 表

Dorp column 列名

删除表

Drop table 表名

到此基础内容已将完毕,可能有所欠缺,如果觉得不足希望同学们给点指导。但是书本上的内容基本就这样了,如果后续有想到内容会补充上的,下一章是数据库的核心内容。select查询!

数据库查询(一)

本章是整本书的核心内容,也是考试的最重点的内容,按照书上的顺序往下讲解。

基本查询:

Select 列名字 –要查询出来的几列,可以使用聚合函数

Into 新表名 –如果要将查询出来的数据添加到新建的表,则在这里写上要创建的新表名

From 来自于的表 – 查询来自于哪个表

Where 条件 –查询约束条件

Group by 列 –按照这个列进行分组,相同的分在同一组。

Having 条件 –在where 中不能使用聚合函数,在这里却可以使用,

Order by 列明 asc| desc – 对某一列进行升序或者降序排序

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
select 学生.姓名 as 大于的姓名               --这里的as是将查询结果的列名取为新的

into linshi

from 学生,选课

where 学生.学生号=选课.学生号

group by 学生.姓名

having count(*)>=2

order by 学生.姓名

这个语句是用来查询选修课程大于等于2的所有学生姓名,并且按照姓名进行升序排序,将查询结果赋予一个新表linshi

在这里要利用group by进行排序,否则执行错误,因为使用having的情况下select后面的列必须在group中出现,

查询的条件约束关键字

比较运算符:就是><= !> not 什么的,

确定范围 between and , not between and 例between @a and @b 介于@a和@b直间

确定集合 in ,not in in后面可以是一个集合,也是in和=的差别

字符匹配 like ,not like 是模糊查询用到的

空值 is null ,is not null 判定是不是空值

多重条件 and ,or ,not 如果三个都存在的话按照 not ,and ,or 的顺序判定

模糊查询的通配符

% :包含零个或者多个字符串的任意字符串,

_ :单个字符

[ ] :指定范围的单个字符,如:在里写上一些字符则在这几个字符里面选择

[^ ] : 指不再这里面的其他字符。

格式:like ‘ ’ 内添加通配符。

复合条件查询:

使用and or not 函数的语句

聚合函数:

包括 sum() , avg() ,min() , max() ,count()

Select中可以使用聚合函数

分组查询:

使用group by进行分组

1
2


1
2
3
4
5
6
7
8
9
Select 性别 ,count (性别)

From 学生

Group by 性别 --将性别相同的分到一个组。

Having是对group by 的进一步查询,相当于where 但是可以使用聚合函数

With cube

在结尾使用此函数将添加一行汇总行,如果查询中有平均成绩,则再添加一行是汇总的全部的平均成绩,(不支持聚合函数)

例:

1
2


1
2
3
4
5
6
select 课程号,avg(成绩),count (学生号)

from 选课

group by 课程号
with cube

img会多一行这样的元组(如果对两个列进行分组(课程号和专业),那么会出现第一列的平均成绩和第二列的平均成绩,和总的平均成绩)

With rollup 的使用

(不支持聚合函数)

对每一个汇总组进行生成行。生成与with一样的行。并且最后还会生成一个与with cube 一样的行、

1
2


1
2
3
4
5
6
7
8
9
select 课程号,专业,avg(成绩)

from 选课,学生

where 学生.学生号=选课.学生号

group by 课程号,专业 --各个课程号的各个专业进行汇总,(如果专业在前面则是每一个专业的平均成绩,课程在前面则是每一门课程的平均成绩,最后再来一次总的平均成绩)

with rollup --对课程号汇总,不计专业,查询课程号的平均成绩,然后再查询都不计的平均成绩

查询了每门专业每门课程的平均成绩和每门课程的平均成绩和总的平均成绩

数据汇总

Compute子句(产生一个附加的汇总行,)

有两种

1
2


1
2
3
4
select 学生号,姓名
from 学生
where 专业='电商'
compute count (学生号)

这类是对前面查询的结果进行汇总,汇总了学生号的个数。单独列出一行

1
2


1
2
3
4
select 学生号,课程号,成绩
from 选课
order by 学生号
compute sum (成绩) by 学生号

对每一个不同的学生号进行汇总,分出多行汇总成绩总和行,在每一个查询结果后面。

数据库查询(二)

连接查询

内连接 Inner join

内连接也叫连接,是最早的一种连接。还可以被称为普通连接或者自然连接,内连接是从结果表中删除与其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。 例:

1
2


1
2
3
4
5
6
7
Select 姓名,选课.课程号,成绩

from 选课Inner join 学生 --进行连接

On 选课.学生号 = 学生.学生号 --此行不可少,

Where 学生.学生号='010002' --条件可以省略

这样就查询了010002所有选课课程号和他的成绩。

上面的语句相当于

1
2


1
2
3
4
5
Select 姓名,选课.课程号,成绩

From 选课,学生

Where 选课.学生号=学生.学生号and 学生.学生号='010002'

这样使用了一个连接符 and 用于合并条件.

自连接

将同一个表的不同行连接起来,连接这样的表需要给表名起两个别名才行,是它在逻辑上称为两个表,在一定程度会方便查询.如要查询成绩大于A同学的所有学生.从而不必涉及子查询. 例:

1
2


1
2
3
4
5
Select a.学生号,a.课程号,a.成绩
From 选课a inner join 选课b --自连接与内链接使用的连接语句相同,都是inner join
On a.课程号='0001' and a.成绩>b.成绩and b.学生号='010003' and b.课程号='0001' --设定条件

group by a.课程号,a.学生号,a.成绩 --按学生号分组,当然不管什么用

这里就是查询了大于010003学生0001课程的成绩的学生的信息

外连接

外连接只限制一个表的数据行,而不限制另一个表的数据行,当然也可以都不限制的。只能用在两个表里面

1、左外连接(对条件的左边不加以限制)left [outer] join 结构: Selec 查找的列

From 表1 left[outer] join 表2

On 表1.列1=表2.列2

例:

1
2


1
2
3
4
5
select 姓名,学生.学生号,选课.课程号

from 学生left join 选课

on 学生.学生号=选课.学生号

将左边表的信息完全显示,一一对应右边的表。

2、右外连接(对右边的不加以限制)right[outer] join

1
2


1
2
3
4
5
Selec 查找的列

From 表1 right[outer] join 表2

On 表1.列1=表2.列2

不再举例

3、全外连接(对两边都不加以限制)full[outer] join

1
2


1
2
3
4
5
Selec 查找的列

From 表1 right[outer] join 表2

On 表1.列1=表2.列2

不再举例。相当于前面说过的

交叉连接

使用关键字 cross join 来创建

例:

1
2


1
2
3
select 姓名,课程号,成绩

from 学生cross join 选课

它不需要添加on或者where来限制连接条件,并且不能用on 来限制,但是可以用where 来限制,如果添加限制,那么最后的结果就会和 inner join 的连接相同

作用:包含了所连接的两个表所有行的全部组合。就是将第一个表的每一项都与第二个表的每一项相连接。

将三个表进行连接

1
2


1
2
3
4
5
6
7
8
9
Select 表1,表2,表3

From 表1 inner join 表2

On 表1.列1=表2.列2

Inner join 表3

On 表1.列1=表3.列3

使用update 可以修改表中的数据

1
2


1
2
3
4
5
update 学生 set 姓名='张小明'

from 学生

where 姓名='张小亮'

将学生表中的行名列中的张凯旭修改为张泽旭

这里还有一个用途,就是可以为所有行都插入同样的信息

例:

1
2


1
2
3
4
5
Update 学生

Set

出生日期 =’1992-01-01’

将在学生表的出生日期列全部插入同样的出生日期。

将查询结果赋予一个定义的变量

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
declare @avg  int

Select @avg=avg(成绩)

From 选课,学生

Where 学生.学生号=选课.学生号and 姓名=@xm

declare @avg int

select @avg =(Select avg(成绩)

From 选课,学生

Where 学生.学生号=选课.学生号and 姓名=@xm)

这里可以使用两种格式进行赋值,

子查询

1、无关子查询

就是指与外部的查询没有关联,可以单独执行内部的查询命令。并且在执行操作的时候优先执行子查询,将子查询的结果赋予外部的查询。

(注:子查询中不可以使用 order by 它只能是对最终的查询结果进行排序。)

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
select 姓名,专业

from 学生

where 学生.学生号in

(select 学生.学生号

from 选课,学生

where 选课.学生号=学生.学生号and 选课.课程号='0002'

group by 学生.学生号

having avg(成绩)>60

)

在这个子查询我选择了一个稍复杂的例子,这里查询了所有选课课程号是0002的并且平均成绩大于60的学生

注意在使用聚合函数的时候只能使用having 代替where 然而使用having的时候又必须要先分组才行,

2、相关子查询

子查询的执行依赖于外部的查询,多数情况下子查询的where 中引用了外部查询的表

相关子查询的执行过程:

1, 子查询为外部查询每执行一次,外部查询将子查询所引用的列的值传给子查询,

2, 如果子查询的任何行与其匹配,则外部查询返回结果行,

3, 再返回第一步,处理外部表的每一行。

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
Select 学生号,课程号,成绩

From 选课 a --外部查询来自于一个选课表,起别名 a

Where 成绩<

(select avg(成绩) --查询平均成绩

From 选课 b --平均成绩来自于选课表 ,起别名 b

Where a.课程号=b.课程号 --将外部的课程号与内部的课程号相关联.

)

这里的语句用来查询比该课程平均成绩低的学生的学生号,课程号,成绩

这里每查询一个课程号的平均成绩,就引用一次外部表的课程号,并且将选课表的成绩与平均成绩相比较,如果成立,则放到查询的行,并且依次比较,再进行查询一次另一个课程号的平均成绩,如此反复,

而无关子查询仅仅将子查询结果出来之后进行赋予外部查询的where 列

3、带有exists的子查询(相关子查询)

Exists是用来判断所查询的结果是否有行,就是是否有结果,如果有结果返回真,如果没有结果,返回假,前面可以加上NOT 就是not exists 则测试的结果就会相反.

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
select 姓名

from 学生

where exists (

select *

from 选课

where 学生号=学生.学生号

and 课程号='0003'

)

判断内部子查询是不是真,如果是真,则将查询到的学生号等于学生表的学生号的值,并且课程号等于0003的学生的姓名查询出来.因为外部的查询只查询了姓名

如果是假的,则返回了空值,.

另一种exists 的用法

1
2


1
2
3
4
5
6
7
8
9
if exists (select *

from 选课

where 课程号='0003')

print '存在'

else print '不存在'

这里使用exists 是比较好用的,它判断了课程号等于0003的是否存在,如果有这个课程号,则打印存在,反之,打印不存在,img

数据库查询(三)

联合查询

联合查询其实就是将连个查询结果进行联合起来,变成更多的结果,

使用SQL语句 union all –这里如果使用了all 那么将会不过虑重复的项。

例:

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
Select 姓名

From 选课,学生

Where 课程号='c001' and 选课.学生号=学生.学生号

Union

Select 姓名

From 选课,学生

Where 课程号='E002' and 选课.学生号=学生.学生号

就是将E002和C001两个课程号的表连接查询起来了

联合查询有两个基本规则、

1、 所有查询的列数和查询的列的顺序必须相同。,

2、 数据类型必须兼容

例:

1
2


1
2
3
4
5
Select 1,2

Union

Select 1.3,5.6

这样的查询是可以联合的,因为他们可以进行隐性转化,将讲个数据格式转换成一个

1
2


1
2
3
4
5
Select '1',3

Union

Select 5,41

这样的也可以转化,虽然上面的是字符型的但是可以转换成整形的1然而如果是字符型的‘zhang’这样的字符,则无法转化

当然最好在查询的时候使用相同的数据类型的数据格式。

对查询结果排序

就是使用order by语句进行排序。

在查询结果的最后一行添加order by 列 ,列

例:

1
2


1
2
3
4
5
Select 学生号,成绩

From 选课

Order by 学生号desc ,成绩 -- 将查询结果先按照学生号降序,按照成绩升序

这里如果不在列的后面添加desc 则默认是ASC升序,

储存查询结果

就是在select 后面使用into 进行储存,将查询到的结果储存在一个新的表里面

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
Slelct 姓名,成绩

Into 新表

From 学生,选课

Where 学生.学生号=选课.学生号

下次再执行 select * from 新表

即可以查询到新表的表项。

使用insert into 将一个或者多个表的查询到的数据赋值到一个新的表里面。

Create table 成绩

(学生号char(7),

课程号char(4),

成绩int

)

Insert into

成绩(学生号,课程号,成绩)

Select * --select 不用再括号里面,不能使用values 、

From 选课

Where 成绩>=80

这样就完成了将查询的值插入到新的表里面

使用控制流语句

用来进行顺序,分支,循环,存储过程,等程序设计。提高编程语言的控制能力

控制流语句一下几项

Set 同于对变量进行赋值,select 也可以当作赋值语句,相对来说select 赋值语句要比set 高级一些,它可以对多个变量进行同时赋值

Begin … end 定义一个语句块

If … else 条件语句

Case 多分支语句

While 循环语句

Continue 重新开始下一个循环

Break 退出本次循环

Goto 无条件转移语句

Return 无条件退出语句

Set 语句

1
2


1
2
3
4
5
Declare  @zhang char(30)

Set @zhang='zhangkaixu'

Select @zhang

同时也可以使用select 语句进行赋值。

1
2


1
2
3
4
5
declare @zhang char(20), @li int 

select @zhang ='zhangkaixu', @li =1233

select @zhang ,@li

可以同时赋值多个值。

Begin … end 语句

该语句可以将多个SQL语句组合成一个语句块。将语句块里面的作为一个单元处理,

例,

1
2


1
2
3
4
5
6
7
8
9
begin

select 姓名

from 学生

where 专业='计类'

end

这个语句在后面的函数部分会用得到

If … slse 语句

判定表达式是否成立,如果成立就执行下面的语句。如果不成立就执行else下的语句

也可以使用 else if进行多重判定。

例:

1
2


1
2
3
4
5
6
7
8
9
10
if exists(select * FROM 学生where 学生号='01003')
print '存在学生号是01003的学生'

else if (select avg (成绩) from 选课where 课程号='0003')>60

print '平均成绩还好'

else

print '不存在或者平均成绩不好'

这里设定了如果学生表有01003的学生则打印第一条,否则如果课程号是0003的平均成绩大于60的话就打印第二条,如果都不是就打印第三条

Case 语句

简单的case 语法

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
Select 学生号,姓名,    --要注意的是CASE语句与其他的查询不同,这里最后一个列后面要加上逗号的。

• Case 专业

• When '计算机' then 'conputer '

• When '通信' then 'tongxin'

• When '电子' then 'dianzi'

End --这里必须加上end 表示结束

From 学生

注:

这里是在case 后列的when后面的几项如果存在就转化为then 后面的字符。就是查询了专业的拼音拼写。如果when后面没有给出列,就显示空。

搜索型的case 语法

搜索型的相当于是新建了一个列,

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Select 学生号,课程号,

Case

• When 成绩>=90 then 'a'

• When 成绩>=80 then 'b'

• When 成绩>=70 then 'c'

• Else 'o'

end as 评分

from 选课

这里将各个分数段的成绩赋予各个评分,并且将最后产生的列改名为‘评分’

注:

其实可以理解为

1
2


1
2
3
4
5
6
7
8
9
10
11
Case 

• When 成绩>=90 then 'a'

• When 成绩>=80 then 'b'

• When 成绩>=70 then 'c'

• Else 'o'

end as 评分

上面的语句是第三个列,只是这个列不是固定的,会随着条件的变化而改变。

Where 语句

Where 可以重复循环一个语句,

通过布尔表达式设定一个条件,当条件成立重复执行上一个语句或者语句块,可以使用break或者continue关键字结束全部循环或者本次循环

例:求1-100的累加和。

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
declare @i int,@j  int

set @i=1

set @j=0

while @i <=100

begin

• set @j=@i + @j

if @j>=1000 break --这里设置了当加到1000以上的时候就停止运算,如果不设置则加到@i=100

• set @i=@i + 1

end

select @i ,@j

和c++类似,在这里begin……end 是设定一个语句块,如果不加以设定,那么就将一直指定第一条 set @j=@i + @j永无休止

Goto 语句

跳转到另一个标号后面的语句,可以相当于while 语句

例:

同样的求1-100的和。

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
declare @i int ,@j int 

select @i=1,@j=0

xunhuan:

set @j=@i+@j

set @i=@i+1

if @i<=100 goto xunhuan

print @j

return 语句

可以理解为只要出现了return 后面的所有都不会再执行,

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
declare @i int ,@j int 

select @i=1,@j=0

xunhuan:

set @j=@i+@j

set @i=@i+1

if @i<=100

return

goto xunhuan

print @j

如上执行出来不会有结果。

函数

创建一个函数,写一个函数结构,在调用的时候只需调用函数的名称就可以,省事方便

系统内置函数

确定性函数

就是说凡是输入特定的值调用这个函数其结果都是相同,确定值的。

非确定性函数

每次输入特定的值,调用函数都不相同,或者可能返回不同的结果。

例:

1
2


1
select dateadd(m,10,'1992-01-05')

查询结果是

1992-11-05 00:00:00.000

每次都是这样的结果

select getdate()

查询结果

不定。

这就是确定函数和非确定函数的差别

数学函数

常用的数学函数

1、 abs 求绝对值 –select abs(-9) 输出9

2、 cos 余弦函数

3、 cot 余切函数

4、 exp 求计算e的X的次方 –select exp(3) 输出20.0855369231877

5、 floor 求仅次于最小值的整数值

6、 log 求自然对数 –select log(5) 默认以e为底数1.6094379124341

7、 pi 常量,圆周率 –select pi() 3.14159265358979

8、 power 求x的y次方 –select power(2,3) 8

9、 rand 随机求数

10、 round 四舍五入 –select round(1.54543134,3) 简化到小数点后3位

11、 sin 正弦函数

12、 square (求平方) – select square(4) 输出16

13、 sqrt 求平方根 –select sqrt(4) 输出2

14、 tan 正切函数 –select tan(57.3) 输出近似1 1弧度≈57.3°

15、 convert 类型转换函数

1
2


1
2
3
rand 

select floor (rand()*100)

这里使用了两个数学函数,一个是取仅次于最小值的整数,还有就是将随机数乘以100,由于随机数是小于1的小数,所以这里将会输出1到100的随机整数。

这里所有的函数在进行调用的时候都需要在函数后面加上括号才可以。

注意的是tan()函数所填写的是弧度的值,而不是角度的值

convert 类型转换函数

可以将字符的类型进行转换,

select convert (char(20),345)

还有要主意的单单的不加select 的函数是不可以执行的、

Cast 也是类型转换

Cast(表达式 as 新类型)

其他的不再解释。

有一个对SQL函数的详细说明网站,大家可以看看

http://www.cnblogs.com/moss_tan_jun/archive/2010/08/23/1806861.html

日期和时间函数

Getdate ()

返回系统当前时间的函数

Dateadd(日期的种类 ,时间间隔,一个时间) 用于求一个指定时间加上一个指定的数值,得到一个新的时间

日期的种类是指日或者年或者月之类的,

select dateadd (day,1,’2002-01-23’)

这里第三个参数时间格式的需要加上引号,第二个不需要加上引号,第一个参数是day或者month或者year。用于返回表达式中的日,月,年

Datediff()

DATEADD()和DATEDIFF()函数可以看作一对表兄弟,有点像乘法与除法。在等式的两端有4个元素:起始日期、时间间隔(datepart)、差值和最终日期。如果已知其中的三个值,就可以求出第4个值。如果在DATEADD()函数中使用起始日期、一个整型值和一个时间间隔,就可返回与起始日期相关的最终日期值。如果提供了起始日期、时间间隔和最终日期,DATEDIFF()函数就可以返回差值。

为了说明这一点,我们选择任意两个日期与一个时间间隔作为参数。这个函数将以所提供的时间间隔为单位返回两个日期之间的差值。要知道1989年9月8日和1991年10月17日之间差了几个月,可编写如下查询代码:

1
2


1
SELECT DATEDIFF(MONTH, '9-8-1989', '10-17-1991')

结果是25个月。如果以日期为单位呢?

1
2


1
SELECT DATEDIFF(DAY, '9-8-1989', '10-17-1991')

结果是769天。

1996年7月2日和1997年8月4日之间差几个星期?

1
2


1
SELECT DATEDIFF(WEEK, '7-2-1996', '8-4-1997')

57星期。甚至可以算出自己的年龄是多少秒:

1
2


1
DECLARE @MyBirthDate   datetime    SET @MyBirthDate   = '7-16-1962'      SELECT DATEDIFF(SS, @MyBirthDate, GETDATE())

结果显示有些人已经活了15亿秒了!

注:

这里的日期型的格式可以是月-日-年,也可以是年-月-日

DATEPART()与DATENAME()函数

这两个函数用于返回datetime或者shortdatetime值的日期部分。DATEPART()函数返回一个整型值;DATENAME()函数返回一个包含描述性文字的字符串。比如,将日期4-29-1988传递给DATEPART()函数,如指定返回月份值,则返回数字4:

1
2


1
SELECT DATEPART(MONTH, '4-29-1988')

而使用相同的参数,DATENAME()函数返回04(这取决于你的机器的本地语言,如果是英文版,那么将返回April):

1
2


1
SELECT DATENAME(MONTH, '4-29-1988')

这两个函数都接收和DATEADD()函数一样的时间间隔参数常量。

字符串函数

主要用来处理二进制类型的数据和字符串数据

Ascii 返回表达式最左边的字符的ASCII的值。

Char 返回整数所代表的ASCII值所对应的字符

Lower 将大写字符转换成小写字符

Upper 将小写字符转化成大写字符

Ltrim 删除字符段开始部分的空格

Rtrim 删除字符段尾部的空格

Right (字符串,数字)返回数字个数以后的字符串,当数字是负数的时候返回NULL

Space(数字) 返回由N个空格组成的字符串

Str(数值,长度,小数点的位置) 将数值型转化成字符串

select str (6645,10,5) 输出6645.00000(一共是十个字符,小数点在左数第五个,)

Stuff (一个字符串,第几个字符,删除N个字符,将这个字符插入到删除掉的字符的位置)

例:

1
2


1
select stuff('zhang',3,2,'kai')

输出: zhkaig 注意必须填写四个参数,否则无法执行。

Substring (字符,第n个字符,返回N个字符)

例:

1
2


1
select substring('zhang',2,3)

输出:han

Reveres (字符) 逆序返回字符串

例“:

1
2


1
select reverse('zhang')

输出 :gnahz

Charindex (字符串,字符串2)返回字符串在字符串2的起始位置。

例:

1
2


1
select charindex('k','zhangkaikxu')

输出 6,返回在第一次出现这个位置的地方的第几个字符。

用户自定义函数

可以分为标量函数和内嵌值表函数和多语句函数。

标量函数

返回类型是除了 text ntext image cursor timestamp 和table 类型以外的数据类型,函数体语句定义在gegin … end 之间,其中包含可以返回值的T-SQL语句

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
create function f_(@kc char(7)) returns float

as

begin

declare @avg float

select @avg=(select avg(成绩) from 选课

where 课程号= @kc )

return @avg

end



declare @zhang char(7)

set @zhang ='0002'

select dbo.f_(@zhang) --这里必须添加函数所有者名dbo 当然也可以自己另定义,系统默认是dbo

这样,一个简单的标量函数就出来了、

内嵌值表函数

以表的形式返回一个返回值,即返回的是一个表,没有用 begin…end 括起来的函数体,其返回的表是一个位于beturn 子句中 select 命令段 从数据库中筛选出来的,相当于是一个参数化的视图

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
alter function f_a (@zy varchar(20)='电商')  returns table

as

return

(select 姓名,性别,年龄

from 学生

where 专业=@zy

)

declare @zhang varchar(20)

set @zhang ='计类'

select * from f_a(@zhang)

这里与标量函数相同,都是相同的格式,只是返回了一个表的格式而已,然后就是在调用函数的时候,是select * form一个表、

多语句函数

可以看作是标量型和内嵌表值型的结合体,返回值是表,但是同样是用begin …end 语句括起来的函数体。

优势是可以生成新的行。而不是单单的查询结果。

1
2


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
create function [table] (@no char(7) ) returns @score table

(学生号char(7),

姓名char(6),

课程名char(10),

学分int ,

成绩int

)

as

• begin

• insert @score select 学生.学生号,学生.姓名,课程.课程名,课程.学分,选课.成绩

from 学生,课程,选课

where 学生.学生号=选课.学生号and 课程.课程号=选课.课程号and 学生.学生号=@no

return

end

declare @no char(7)

set @no='010002'

select* from [table] (@no)

注意的是这里调用函数的时侯也是使用select * from 函数名。(引用表的都要这样使用)Return要在begin …end之间。