SQL Server数据库学习_T-SQL常用语句

T-SQL语句 实例(一)

1. 创建数据库

例:创建数据库“STUDENT2”,包含一个主数据文件和一个事务日志文件。

主数据文件的逻辑名为“STUDENT2_DATA”,操作系统文件名为“STUDENT2_DATA.MDF”,初始容量大小为5M,最大容量为20M,文件的增长量为20%。

事务日志文件的逻辑文件名为“STUDENT2_LOG”,物理文件名为“STUDENT2_LOG.LDF”,初始容量大小为5M,最大容量为10M,文件增长量为2M。

数据文件与事务日志文件分别存放在E盘和G盘的“DATA”
文件夹中。

首先在E盘和G盘各创建一个新的文件夹,名称是“DATA”。 CREATE DATABASE STUDENT2

ON
PRIMARY

(NAME = ‘STUDENT2_DATA’,

FILENAME = ‘D:\DATA\STUDENT2_DATA.MDF’ ,

SIZE = 5MB,

MAXSIZE = 20MB,

FILEGROWTH = 20%)

LOG ON

(NAME =‘STUDENT2_LOG’,

FILENAME = ‘G:\DATA\ STUDENT2_LOG. LDF’,

SIZE = 5MB,

MAXSIZE = 10MB,

FILEGROWTH = 2MB)

例:创建一个指定多个数据文件和日志文件的数据库。该数据库名称为STUDENTS,有1个5MB和1个10MB的数据文件和2个5MB的事务日志文件。

数据文件逻辑名称为STUDENTS1和STUDENTS2,物理文件名为STUDENTS1.mdf和STUDENTS2.ndf。主文件是STUDENTS1,由PRIMARY指定,两个数据文件的最大尺寸分别为无限大和100MB,增长速度分别为10%和1MB。

事务日志文件的逻辑名为STUDENTSLOG1和STUDENTSLOG2,物理文件名为STUDENTSLOG1.ldf和STUDENTSLOG2.ldf,最大尺寸均为50MB,文件增长速度为1MB。

要求数据文件和日志文件分别存放在E盘和G盘的DATA文件夹下。

CREATE
DATABASE STUDENTS

ON PRIMARY

(NAME=STUDENTS1,

FILENAME=‘E:\DATA\STUDENTS1.mdf’,

SIZE=5,

MAXSIZE=unlimited,

FILEGROWTH=10%),

FILEGROUP FILEG1

(NAME= STUDENTS2,

FILENAME=‘E:\DATA\STUDENTS2.ndf’,

SIZE=10,

MAXSIZE=100,

FILEGROWTH=1)

LOG ON

(NAME=STUDENTSLOG1,

FILENAME=‘G:\DATA\STUDENTSLOG1.ldf’,

SIZE=5,

MAXSIZE=50,

FILEGROWTH=1),

(NAME=STUDENTSLOG2,

FILENAME=‘G:\DATA\STUDENTSLOG2.ldf’,

SIZE=5,

MAXSIZE=50,

filegrowth=1)

2. 修改数据库

例:为STUDENT2数据库增加容量,原来数据文件STUDENT2_DATA的初始分配空间为5M,现在将STUDENT2_DATA的分配空间增加至20M。

ALTER DATABASE STUDENT2

MODIFY
FILE

(NAME= STUDENT2_DATA,

SIZE=20MB)

【例】为数据库STUDENT2 增加数据文件STUDENT2_DATA1,初始大小10M,最大50M,按照5%增长。

ALTER DATABASE STUDENT2

ADD
FILE

(NAME = ‘STUDENT2_DATA1’,

FILENAME = ‘F:\DATA\ STUDENT2_DATA1.NDF’,

SIZE = 10MB,

MAXSIZE = 50MB,

FILEGROWTH = 5%)

【例】将数据库STUDENT2 中增加的数据文件STUDENT2_DATA1删除。

ALTER DATABASE STUDENT2

REMOVE FILE STUDENT2_DATA1

删除数据库

如,DROP
DATABASE STUDENT2

3. 创建表

例:在数据库“STUDENT1”创建学生信息表(XS),包括学号(主键)、姓名、性别字段。其中性别字段只能接受“男”或“女”,不能接受其他数据。

USE STUDENT1

GO

CREATE
TABLE XS

(学号
char(12) PRIMARY KEY,

姓名 char(20) ,

性别
nchar(1) CONSTRAINT chk_sex CHECK(性别 =‘男’ or 性别 = ‘女’)

)

例:在数据库“teaching”下创建“课程表(course)”,表结构如下所示。

USE
teaching

GO

CREATE
TABLE course

(cno char(4) PRIMARY
KEY,

cname nvarchar(20) NOT NULL ,

classhour tinyint,

credit tinyint

)

4. 修改表

例:在XS表中修改“姓名”字段的属性,使该字段的数据类型为nvarchar(10),允许为空。

USE STUDENT1

GO

ALTER
TABLE XS

ALTER
COLUMN 姓名
nvarchar(10) NULL

例:在学生信息表XS中添加“年龄”字段,数据类型为整型,可以为空。

USE STUDENT1

GO

ALTER
TABLE XS

ADD 年龄 int

例:删除学生信息表XS中的“年龄”字段。

USE STUDENT1

GO

ALTER
TABLE XS

DROP
COLUMN 年龄

5. 约束

(1)一个表中最多只能有一个主键PRIMARY KEY ,且主键列不允许空值。

USE STUDENT1

GO

CREATE
TABLE XS

(
学号 char(6) PRIMARY KEY,

身份证号 char(20) ,

姓名 char(8) NOT NULL,

专业名 varchar(10)
)

(2)UNIQUE约束指定表中某一个列或多个列不能有相同的两行或两行以上的数据存在。

USE STUDENT1

GO

CREATE
TABLE XS1

(
学号 char(6) PRIMARY KEY,

身份证号 char(20) UNIQUE,

姓名 nvarchar(8) NOT NULL,

专业名 nvarchar(10),

)

(3)CHECK约束:通过指定的逻辑表达式来限制某列的取值范围。

USE STUDENT1

GO

CREATE TABLE XS1
( 学号 char(6) PRIMARY KEY,

身份证号 char(18)
UNIQUE,

姓名 nvarchar(8) NOT NULL,

专业名 nvarchar(10),

性别 nchar(1) CHECK (性别=‘男’ or 性别=‘女’)

)

(4) DEFAULT约束:当使用INSERT语句插入数据时,如果没有为某一个列指定数据,那么DEFAULT约束就在该列中输入一个默认值。

USE STUDENT1

GO

CREATE
TABLE ST

(学号 char(6) PRIMARY KEY,

身份证号 char(18) UNIQUE,

姓名 nvarchar(8) NOT NULL,

专业名 nvarchar(10),

性别 nchar(1) CONSTRAINT chk_1

CHECK (性别=‘男’ or 性别=‘女’),

出生时间 smalldatetime NOT NULL,

总学分 tinyint,

入学日期 datetime DEFAULT getdate( )

)

(5)外键约束:定义一个或多个列,这些列可以引用同一个表或另外一个表中的主键约束列或UNIQUE约束列。

通过创建外键约束可以实现表和表之间的关联关系。

例: 外键和通过表约束设置主键的例子:

USE STUDENT1

GO

CREATE TABLE SC

( 学号 char (6) FOREIGN
KEY REFERENCES ST(学号),

课程号 char(4),

成绩 int ,

PRIMARY KEY(学号,课程号)

)

6. 表的插入

例:在STUDENT1数据库的学生(ST)表中插入一行数据。

USE STUDENT1

GO

INSERT
into ST(学号,姓名,性别,出生时间)

VALUES(‘150111’,‘杨丽’,‘女’,’1996-10-3’)

INSERT
into ST VALUES(‘150112’,‘130212199707120895’,‘张强’,‘网络工程’,‘男’,‘1997-7-12’,150,‘2010-9-1’)

7. 修改表中的数据

(1).例:在STUDENT1数据库的学生(ST)表中的“性别”字段的值设为“男”。

USE STUDENT1

GO

UPDATE
ST

SET 性别=‘男’

(2). USE STUDENT1

GO

UPDATE ST

SET 性别=‘女’

WHERE 姓名=‘杨丽’

(3). 例:在STUDENT1数据库的学生表中添加一字段“备注”nvarchar(20);“备注”字段信息为’已毕业’ 。

①USE STUDENT1

GO

ALTER TABLE ST

Add 备注
nvarchar(20)

②UPDATE ST

SET 备注=‘已毕业’

(4). 例:在学生表中,将学号为‘150112’的学生姓名改为“王武”。

USE STUDENT1

GO

UPDATE ST

SET 姓名=‘王武’

WHERE 学号=‘150112’

8. 删除表中的数据

(1)例:删除学生表中,将学号为‘150112’的学生记录删除。

USE STUDENT1

DELETE
FROM ST

WHERE 学号 = ‘150112’

(2)使用TRUNCATE TABLE清空表数据

语法格式:TRUNCATE TABLE table_name

TRUNCATE TABLE与不含有WHERE子句的DELETE语句在功能上相同。但是,TRUNCATE
TABLE速度更快,其使用更少的系统资源和事务日志资源。

例:清空学生表中的数据

TRUNCATE TABLE
ST

9. 使用MERGE语句插入、修改和删除数据

SQL Server 2008中的MERGE语句能做很多事情,它的功能是根据源表对目标表执行插入、更新或删除操作。

最典型的应用就是进行两个表的同步。

假设数据库中有两个表:产品表“Product”和新产品表“ProductNew”。

源表:Product

CREATE TABLE Product

( ProductID char(7) PRIMARY KEY, --产品编号

ProductName nvarchar(30) NOT NULL, --名称

Price decimal(13,2) DEFAULT
0 ) --价格INSERT INTO Product
Values (‘4100037’,‘优盘’,50), (‘4100038’,‘鼠标’,30)

目标表:ProductNew

CREATE TABLE ProductNew

(ProductID char(7) PRIMARY KEY,

ProductName nvarchar(30) NOT NULL,

Price decimal(13,2) DEFAULT
0 )

MERGE ProductNew d USING Product s

ON s.ProductID = d.ProductID

WHEN NOT MATCHED THEN INSERT(
ProductID,ProductName,Price)

VALUES(s.ProductID,s.ProductName,s.Price);

注意:源表可以是表,也可以是一个子查询语句。格外强调一点,MERGE语句最后的分号是不能省略的!

修改单价:UPDATE Product SET Price=55 WHERE ProductID= ‘4100037’

插入和修改都同步:

MERGE ProductNew d USING Product s

ON s.ProductID = d.ProductId

WHEN NOT MATCHED THEN INSERT(
ProductID,ProductName,Price)

VALUES(s.ProductID,s.ProductName,s.Price)

WHEN MATCHED THEN

UPDATE SET d.ProductName = s.ProductName,
d.Price = s.Price;

删除数据:DELETE Product WHERE ProductID= ‘4100037’

插入、修改和删除都同步:

MERGE ProductNew d USING
Product s

ON s.ProductID=d.ProductId

WHEN NOT MATCHED BY TARGET

THEN INSERT(ProductID,ProductName,Price)

VALUES(s.ProductID,s.ProductName,s.Price)

WHEN NOT MATCHED BY SOURCE
THEN DELETE

WHEN MATCHED THEN

UPDATE SET d.ProductName = s.ProductName,
d.Price = s.Price;

10. 删除表

删除表就是将表中数据和表的结构从数据库中永久性地去除。表被删除之后,就不能再恢复该表的定义。

例: 删除学生表(ST)

DROP
TABLE ST

11. 投影查询

【例1】查询 “teaching”数据库中学生的姓名、性别和专业。

USE
teaching

SELECT
sname, ssex, specialty FROM student

【例2】查询
“teaching”库中“course”的所有记录。

USE
teaching

SELECT

  • FROM course

注:用“*”可以表示表中所有的列。

【例3】查询
“teaching”中“学生表”的专业名称,滤掉重复行。

USE
teaching

SELECT
DISTINCT specialty

FROM student

用DISTINCT关键字可以过滤掉查询结果中的重复行。

【例4】查询“teaching”库中“course”表的前三行信息。

USE
teaching

SELECT
top 3 * FROM course

【例5】查询“teaching”库中“course”表的前50%行的信息。

USE
teaching

SELECT
top 50 percent * FROM course

修改查询结果中的列标题(显示标题)——起别名

【例6】查询“student”表中所有学生的学号、姓名,结果中各列的标题分别指定为汉字学号和姓名。

USE
teaching

SELECT sno AS 学号, sname AS 姓名

FROM student

或:

USE
teaching

SELECT
sno 学号, sname 姓名

FROM student

或:

USE
teaching

SELECT 学号=sno, 姓名=sname

FROM student

计算列值

【例7】查询“SC”表,按150分制计算成绩。

USE
teaching

SELECT
sno, cno, score150=score*1.50
FROM sc

12. 选择查询

【例1】查询“teaching”库“sc”表中成绩大于等于60的学生的学号、课程号和成绩。

USE
teaching

SELECT * FROM sc

WHERE score>=60(关系表达式)

【例2】查询“teaching”库中“计算机”专业的“男”生的信息。(多条件的逻辑表达式)

USE
teaching

SELECT * FROM student

WHERE specialty=‘计算机’ and
ssex=‘男’

【例3】查询“teaching”库中“计算机”专业的或“男”生的信息。

USE
teaching

SELECT * FROM student

WHERE specialty=‘计算机’ or ssex=‘男’

【例4】查询“teaching”库中成绩在80到90之间的学生的学号、课程号和成绩。

USE
teaching

SELECT * FROM sc

WHERE score BETWEEN 80 AND 90

或:

USE
teaching

SELECT * FROM sc

WHERE score>= 80 AND score<=90

【例5】查询“teaching”库中”计算机”和”网络”专业的学生的姓名、学号和专业。

USE
teaching

SELECT sname,sno,specialty

FROM student

WHERE specialty IN(‘计算机’ ,‘网络’)

使用[NOT] LIKE关键字(模糊查找):LIKE关键字搜索与指定模式匹配的字符串、日期或时间值。模式包含要搜索的字符串,字符串中可包含4种通配符的任意组合。

【例6】通配符的示例

LIKE ‘AB%’

返回以“AB”开始的任意字符串。

LIKE ‘%abc’

返回以“abc”结束的任意字符串。

LIKE ‘%abc%’

返回包含“abc”的任意字符串。

LIKE ‘_ab’

返回以“ab”结束的三个字符的字符串。

LIKE ’ [ACK]% ’

返回以“A”、“C”或“K”开始的任意字符串。

LIKE ’ [A-T]ing’

返回四个字符的字符串,结尾是“ing”,首字符的范围从A到T。

LIKE 'M[^c]% ’

返回以“M”开始且第二个字符不是“c”的任意长度的字符串。

【例7】查询“teaching”库中所有姓“张”的学生的信息。

USE teaching

SELECT * FROM student

WHERE sname like ‘张%’

【例8】查询“teaching”库中所有“成绩”为空的学生的学号、课程号和成绩。

USE teaching

SELECT * FROM sc

WHERE score IS NULL

复合条件查询的优先级问题:

【例9】从“teaching”库的“student”表中查询所有“计算机”和“通信”专业的“女”生的信息。

USE teaching

SELECT * FROM student

WHERE ssex=‘女’ AND

(specialty=‘计算机’

OR specialty=‘通信’)

13. 聚合函数查询

聚合函数可以实现数据集合的汇总或是求平均值等各种运算。

【例1】在“teaching”库中查询“sc”表中成绩的平均值,平均值显示列标题为“平均成绩”。

USE
teaching

SELECT avg(score) AS 平均成绩

FROM
sc

【例2】查询学生的人数。

USE
teaching

SELECT count(*) AS 学生人数

FROM student

【例3】查询专业的种类(相同的按一种计算)。

USE
teaching

SELECT count (DISTINCT specialty)

AS 专业种类数 FROM student

【例4】在“teaching”库中查询1302001号学生的平均成绩。

USE
teaching

SELECT avg(score) AS 平均成绩

FROM sc

WHERE sno= ‘1302001’

14. 分组查询

1. 简单分组

没有使用CUBE或ROLLUP关键字的分组技术。

【例1】查询“teaching”库中男生和女生的人数。

USE
teaching

SELECT ssex, count(ssex) 人数

FROM student

GROUP BY ssex

HAVING关键字可以对查询和统计的结果进行进一步的筛选

【例2】在“sc”表中查询选修了两门及以上课程的学生学号和选课数。

USE
teaching

SELECT sno,COUNT(cno) 选修课程数 FROM sc

GROUP BY sno

HAVING COUNT(cno)>=2

2. CUBE和ROLLUP 的使用

【例3】在“teaching”库中查询“sc”表,求被选修的各门课程的平均成绩和选修该课程的人数,及所有课程的总平均成绩和总选修人数。

USE teaching

SELECT cno, AVG(score) AS ‘平均成绩’,COUNT(sno)
AS ‘选修人数’

FROM sc

GROUP BY cno

WITH CUBE

【例4】在“teaching”库中查询“student”表,统计各专业男生、女生人数及每个专业的学生人数和男生总人数、女生总人数以及所有学生总人数。

USE teaching

SELECT specialty,ssex,COUNT(*) AS ‘人数’

FROM student

GROUP BY specialty,ssex

WITH CUBE

【例5】统计在“teaching”库中每个专业的男女生人数,每个专业的总人数和所有学生总人数。

USE teaching

SELECT specialty,ssex,COUNT(*) AS ‘人数’ FROM student

GROUP BY specialty,ssex

WITH ROLLUP

15. 数据汇总

【例1】在“teaching”中查询“计算机”专业的学生的学号、姓名和性别,并统计学生总人数。

USE teaching

SELECT sno,sname,ssex

FROM student

WHERE specialty= ‘计算机’

COMPUTE COUNT(sno)

【例2】在“teaching”库中查询所有学生的选课信息,并计算每个学生的平均成绩。

USE teaching

SELECT sno,cno,score

FROM sc

ORDER BY sno

COMPUTE avg(score) BY sno

16. 内连接

【例1】
从“teaching”库中查询每个学生的姓名、课程号和成绩。

USE teaching

SELECT student.sname, sc.cno, sc.score

FROM student INNER JOIN sc ON student.sno=sc.sno

也可以利用下面的语句来实现:

SELECT student.sname, sc.cno, sc.score

FROM student,sc

WHERE
student.sno=sc.sno

注意:在列名不同时,列名前可以不加表名,但有时也会加上表名,以增强可读性。

【例2】
从“teaching”库中查询“计算机”专业的学生所选课程的平均分。

USE teaching

SELECT b.cno, avg(b.score) as 平均分

FROM student a INNER JOIN sc b

ON a.sno=b.sno and a.specialty=‘计算机’

GROUP BY b.cno

注:为了简化输入,可以在查询中使用别名,以缩写表名;可以在FROM子句中为表定义一个临时别名,在查询中引用。

带筛选条件的三个表的内连接:查询成绩在75分以上的学生的学号、姓名,选修课的课程号、课程名、成绩。

USE teaching

SELECT C.cno, C.cname, A.sno, A.sname,
B.score FROM student AS A JOIN SC AS B

ON A.sno=B.sno AND B.score>75

JOIN course AS C on B.cno=C.cno

(或where B.score>75 放在最后)

17. 自连接

连接操作也可以在同一张表内进行自身连接,即将同一个表的不同行连接起来。

自连接必须为表指定两个别名,使之在逻辑上成为两张表。

【例8-3】从“teaching”库中查询同名学生的信息。

USE teaching

SELECT * FROM student a INNER JOIN student b ON a.sname=b.sname AND a.sno<>b.sno

18. 外连接

(1)外连接分为3种类型

左外连接:对连接条件中左边的表不加限制;

右外连接:对右边的表不加限制;

全外连接: 对两个表都不加限制,所有两个表中的行都会包括在结果集中。

【例1】在“teaching”库中查询每个学生及其选修课程的成绩情况(含未选课的学生信息)。

USE teaching

SELECT student.*,sc.cno,sc.score

FROM student LEFT JOIN sc

ON student.sno=sc.sno

【例2】在”teaching”库中查询每个学生及其选修课程的情况(含未选课的学生信息及未被选修的课程信息)。

USE teaching

SELECT course.*,sc.score,student.sname,
student.sno

FROM course FULL JOIN sc

ON course.cno=sc.cno FULL JOIN student

ON student.sno=sc.sno

[例3]查询所有男生的选课信息,包括没选课的男生。

USE 教学库

SELECT student.*,sc.cno,sc.score

FROM student LEFT JOIN sc

ON student.sno=sc.sno and ssex=‘男’

或where ssex=‘男’

19. 子查询

USE teaching

SELECT sno, sname, specialty

FROM student

WHERE specialty=

(SELECT specialty

FROM student

WHERE sname=‘沈艳’)

【例2】在“teaching”库中查询C001号课的考试成绩比“郑丽”高的学生的学号和姓名。

USE teaching

SELECT student.sno,sname

FROM student,sc

WHERE student.sno = sc.sno and cno=‘C001’

and score>(SELECT score FROM sc WHERE
cno=‘C001’ and sno=(SELECT sno FROM
student WHERE sname=‘郑丽’))

2) SOME、ANY、ALL和IN子查询

能确切知道子查询返回的是单值时,可以用>,<,=,>=,<=,!=或<>等比较运算符。

【例3】查询计算机专业年龄最大的学生的学号和姓名。

USE teaching

SELECT sno,sname FROM student WHERE
sage>= ALL

(SELECT sage FROM student WHERE specialty=‘计算机’) AND specialty=‘计算机’

【例4】在“teaching”库中查询选修了“C001”号课程的学生姓名和所在专业。

USE teaching

SELECT sname,specialty

FROM student

WHERE sno IN

(SELECT sno FROM sc

WHERE cno=‘C001’)

3)子查询结果作为主查询的查询对象

【例5】在“teaching”库中查询有2个以上学生平均成绩超过80分的班级(用年级和专业表示)。

USE teaching

SELECT grade,specialty FROM student s,

(SELECT sno FROM SC GROUP BY sno

HAVING AVG(score) >=80) ss

WHERE s.sno=ss.sno

GROUP BY grade,specialty

HAVING COUNT(*)>=2

USE teaching

SELECT grade,specialty FROM student

WHERE sno IN (SELECT sno FROM SC GROUP BY
sno

HAVING AVG(score) >=80)

GROUP BY grade,specialty

HAVING COUNT(*)>=2

1)比较子查询

【例6】在“teaching”库中查询成绩比该课的平均成绩低的学生的学号、课程号、成绩。

USE teaching

SELECT sno,cno,score

FROM
sc a

WHERE score<( SELECT avg(score) FROM sc b
WHERE b.cno=a.cno)

【例7】在“teaching”库中查询有2门以上课程的成绩在80分以上的学生的学号、姓名、年级和专业。

SELECT sno,sname,grade,specialty

FROM student s

WHERE (SELECT COUNT(*) FROM sc

WHERE sc.sno=s.sno

and score >=80)>=2

注:EXISTS子查询的目标属性列表达式一般用*表示,因为带EXISTS的子查询只返回真或假值,给出列名无实际意义。

【例8】在“teaching”库中查询所有选修了C004号课程的学生姓名。

USE teaching

SELECT sname FROM student

WHERE EXISTS (SELECT * FROM sc

WHERE sno=student.sno AND cno= ‘C004’)

20. 集合查询

【例1】查询选修了课程C001或课程C004的学生的姓名。

USE teaching

SELECT sname FROM sc,student

WHERE cno=‘C001’ and sc.sno=student.sno

UNION

SELECT sname FROM sc,student

WHERE cno=‘C004’ and sc. sno=student.sno

又例:查询所有学生的学号、姓名和所有教师编号、姓名。

EXCEPT(差)和INTERSECT查询(交)

【例2】查询没有选课的学生的学号。

SELECT sno FROM student

EXCEPT

SELECT sno FROM sc

【例3】查询选了既选修了C001又选修了C004课程的学生的学号。

SELECT sno FROM sc WHERE cno=‘C001’

INTERSECT

SELECT sno FROM sc WHERE cno=‘C004’

21. 对查询结果排序

【例4】查询“teaching”库中“女”学生的姓名和专业,并按姓名升序排列。

USE
teaching

SELECT sname,specialty

FROM student

WHERE ssex=’女’

ORDER BY sname ASC

【例5】查询“sc”中学生的成绩和学号,并按成绩(降序)排列,若成绩相同按学号(升序)排列。

USE
teaching

SELECT sno,score FROM sc

ORDER BY score DESC,sno ASC

【例6】使用TOP关键字查询“course”表中“学分”最高的前两门课。

USE
teaching

SELECT
TOP 2 cname,credit

FROM course
ORDER BY credit DESC

3 22. 存储查询结果

【例7】查询的学生姓名、学号、课程名、成绩的相关数据存放在表“成绩单”中。

USE teaching

SELECT sname,student.sno, cname, score

INTO 成绩单 FROM
student,sc,course

WHERE student.sno=sc.sno

AND course.cno=sc.cno

23. 数据操作中使用select语句

【例1】在“teaching”库中创建“sc”表的一个副本“成绩表”,将“sc”中成绩大于80的数据添加到“成绩表”中,并显示表中内容。

USE teaching

GO

CREATE TABLE 成绩表

(学号 char(7),

课程号 char(4) ,

成绩 int )

GO

INSERT INTO 成绩表(学号,课程号,成绩)

SELECT * FROM sc

WHERE score>=80

GO

SELECT * FROM 成绩表

【例2】将13级计算机专业张明明选修的“C001”号课的成绩改为92分。

方法一:使用SELECT子句

UPDATE sc SET score=92

WHERE cno=‘C001’ AND sno=

(SELECT sno FROM student

WHERE sname=‘张明明’ AND grade=‘13级’

AND specialty=‘计算机’)

方法二:使用JOIN内连接

UPDATE sc SET score=92 FROM sc

JOIN student ON student.sno=sc.sno

WHERE cno=‘C001’ AND

sname=‘张明明’ AND grade=‘13级’

AND specialty=‘计算机’

【例3】在“teaching”库中将13级计算机专业张明明选修的C001号课删除。

方法一:使用SELECT子句

DELETE sc WHERE cno=‘C001’

AND sno=

(SELECT sno FROM student

WHERE sname=‘张明明’ AND grade=‘13级’

AND specialty=‘计算机’)

方法二:使用JOIN内连接

DELETE sc FROM sc

JOIN student ON student.sno=sc.sno

WHERE cno=‘C001’ AND

sname=‘张明明’ AND grade=‘13级’

AND
specialty=‘计算机’

24. 创建视图

[例1]创建视图s_c_sc ,包括地理信息专业的学生的学号、姓名,和他们选修的课程号、课程名和成绩。

USE teaching

GO

CREATE VIEW s_c_sc

AS

SELECT
student.sno,sname,course.cno,cname,score

FROM student,sc,course WHERE
student.sno=sc.sno

AND course.cno=sc.cno AND sdept=‘地理信息’

GO

[例2]创建库存统计视图inve_count
,求每种商品的总库存数量,要求包括商品编号和商品名称。

USE inventory

GO

CREATE VIEW inve_count

AS

SELECT goods.gno,gname,SUM(number) AS
snumber

FROM goods,invent

WHERE goods.gno= invent.gno

GROUP BY goods.gno,gname

GO

25. 修改视图

[例3]修改库存统计视图inve_count
,求每种商品的总库存数量和所在仓库的个数
,要求包括商品编号和商品名称。

ALTER VIEW inve_count

AS

SELECT goods.gno,gname,SUM(number) AS
snumber, COUNT(stno) AS storenum

FROM goods,invent

WHERE goods.gno= invent.gno

GROUP BY goods.gno,gname

GO

【例4】在视图上创建视图:创建“goodscount”商品统计视图,求每种商品的总库存数量和和总价值,要求包括商品编号和商品名称。

USE inventory

GO

CREATE VIEW goodscount

AS

SELECT goods.gno, goods.gname, snumber,
snumber *price as sumprice

FROM goods, inve_count

WHERE goods.gno= inve_count .gno

GO

26. 使用视图

【例1】在查询窗口中查询s_c_sc视图,统计“C++语言”课程的总分和平均分。

USE teaching

SELECT sumscore=SUM(score),
avgscore=AVG(score) FROM s_c_sc

WHERE cname=‘C++语言’

【例2】查询“inve_count”视图中“冰箱”的商品统计信息。

USE inventory

SELECT * FROM inve_count

WHERE gname=‘冰箱’

使用视图修改基本表中数据

修改视图的数据,其实就是对基本表进行修改,因为真正存放数据的地方是基本表而不是视图。

同样使用INSERT、UPDATE、DELETE语句来完成数据的插入、修改和删除。

注意:并不是所有的视图都可以更新数据,只有对满足可更新条件的视图才能更新数据。

可更新条件*:

(1)任何通过视图的数据修改(包括UPDATE、INSERT和DELETE语句)都只能引用一个基本表的列。

①如果视图数据为一个表的行、列子集,则此视图可更新(包括UPDATE、INSERT和DELETE语句);但如果视图中没有包含表中某个不允许取空值又没有默认值约束的列,则不能利用视图插入数据。

②如果视图所依赖的基本表有多个时,完全不能向该视图添加(INSERT)数据。

③若视图依赖于多个基本表,那么一次修改只能修改(UPDATE)一个基本表中的数据。

④若视图依赖于多个基本表,那么不能通过视图删除(DELETE)数据。

(2)视图中被修改的列必须直接引用表列中的基础数据。不能是通过任何其他方式对这些列进行派生而来的数据,比如通过聚合函数、计算(如表达式计算)、集合运算等。

(3)被修改的列不应是在创建视图时受GROUP
BY、HAVING、DISTINCT或TOP子句影响的。

【例3】通过“male_view”视图向“student”表中插入一个“男”生。

INSERT INTO male_view VALUES (‘1501005’, ‘张三’, ‘男’, 19)

如果通过“male_view”视图向“student”表中插入一个“女”生,也可以完成.

如果不希望用户通过“male_view”视图插入“女”生,在创建“male_view”视图时应该使用WITH CHECK OPTION选项。

命令如下:

CREATE VIEW male_view AS

SELECT sno, sname, ssex, sage, en_time,
specialty, grade

FROM student WHERE ssex = ‘男’

WITH CHECK OPTION

27. 删除视图

【例】删除前面例子创建的s_c_sc视图。

USE teaching

GO

DROP VIEW s_c_sc

GO

28. 创建索引

[例1] 根据教学库中学生表的姓名列的升序创建一个名为index_sname的普通索引。

USE 教学库

GO

CREATE INDEX index_sname

ON student(sname)

GO

[例2] 根据仓库库存数据库中商品表的商品名称、生产商创建一个名为商品_生产商的唯一性复合索引,其中商品名称为升序,生产商为降序。

USE 仓库库存

GO

CREATE UNIQUE INDEX gname_pro

ON goods(gname ASC, producer DESC)

GO

间接创建索引

在定义表结构或修改表结构时,如果定义了主键约束(PRAMARY KEY)或者唯一性约束(UNIQUE),可以间接创建索引。

[例3] 创建一个s1表,并定义了主键约束。

USE teaching

GO

CREATE TABLE s1(

sno
char(6) PRIMARY KEY,

sname char(8) )

此例中,就按sno升序创建了一个聚集索引。

[例4] 创建一个教师表,并定义了主键约束和唯一性约束。

USE teaching

GO

CREATE TABLE teacher(

tno
char(6) PRIMARY KEY,

tname char(8) UNIQUE )

此例中,创建了两个索引,按tno升序创建了一个聚集索引,按tname升序创建了一个非聚集唯一索引。

29. 创建索引视图

视图必须满足下列要求才可以创建索引:

(1)当执行 CREATE VIEW 语句时,ANSI_NULLS
和 QUOTED_IDENTIFIER 选项必须设置为 ON。

(2) 创建视图引用的表时,ANSI_NULLS 选项必须设置为 ON。

(3)视图不能引用任何其它视图,只能引用基本表。

(4)视图引用的所有基本表必须与视图位于同一个数据库中,并且所有者也与视图相同。

(5)必须使用 SCHEMABINDING 选项创建视图。

(6)必须已使用 SCHEMABINDING 选项创建了视图中引用的用户定义的函数。

(7)表和用户定义的函数必须由两部分的名称引用。

(8)视图中的表达式所引用的所有函数必须是确定性的。

(9)选择列表不能使用 * 或
table_name.* 语法指定列。必须显式给出列名。

【例】创建一个“female_view”女生视图,并为该视图按“sno”升序创建一个具有唯一性的聚集索引。

创建视图:

CREATE VIEW female_view WITH SCHEMABINDING

AS

SELECT sno,sname,ssex,specialty FROM
dbo.student

WHERE ssex= ‘女’

创建索引:

CREATE UNIQUE CLUSTERED INDEX index_female
ON female_view(sno)

30. 查看索引信息

使用T-SQL语句查看索引信息

可以使用系统存储过程sp_help index或sp_help来查看索引信息

(1) 使用系统存储过程sp_helpindex查看索引基本信息

EXEC
sp_helpindex student

(2) 使用系统存储过程sp_help查看索引及其他信息

EXEC
sp_help student

31. 删除索引

当一个索引不再需要时,可以将其从数据库中删除,以释放占用的存储空间。

注意**:(1)必须删除约束,才能删除PRIMARY KEY或UNIQUE约束使用的索引。

(2)删除某个表时,会自动删除在此表上创建的索引。

[例]删除学生表中的“Index_sname”索引。

USE teaching

GO

DROP
INDEX student.Index_sname

GO

你可能感兴趣的:(笔记)