SQL-server2012使用T-SQL语句对数据库、模式、表、视图、约束、触发器、变量、函数的相关操作

博主整理了包含:数据库、模式、表、视图、约束、触发器、变量、函数等等SQL-server中差不多所有类型的sql语言,希望对你有所帮助,后续有新的发现还会继续更新的!

学习之前要解有关数据库、文件、日志文件等属性:

1)逻辑名称:数据文件和日志文件名称;
2)文件类型:数据文件及日志文件 ;
3)文件组:各个数据文件所属的文件组名称;
4)初始大小:文件的最原始大小;
5)自动增长:文件按指定的大小增长,也可限制到最大容量;
6)路径:存放文件的物理目录;
7)文件名:显示数据文件和日志文件的物理名称;
默认数据库属性:
1)主数据文件为xx.mdf,日志文件为xx_log.ldf;
2)只有一个文件组Primary;
3)主数据文件初始大小为5MB(sql server2008及低版本初始大小基本都为3MB),增量为1MB;
4)日志文件初始大小1MB,增量为10%;
5)5) 主数据文件和日志文件都存放在C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA目录下,文件分别为xx.mdf 和xx_log.ldf 。

1. 数据库的修改
修改数据库的命令如下:

Alter database database_name
{
     add file <filespec>[,…n] [to filegroup filegroupname]
add log file <filespec>[,…n]
remove file logical_file_name [with delete]
modify file <filespec>}

增加数据文件
例如:在数据库中增加数据文件db2,初始大小为10MB,最大大小为50 MB,按10%增长;

alter database student 
add file 
(
	name = db2,
	filename = 'D:\db2.ndf',
	size = 10mb,
	maxsize = 50mb,
	filegrowth = 10%

)

增加日志文件
例:在数据库student中添加日志文件,保存在D盘中,初始大小为1MB,最大无限制,增长方式按照1MB增长;

alter database student
add log file
(
	name = stu_log2,
	filename = 'D:\stu_log2.ldf',
	size = 1mb,
	maxsize = unlimited,
	filegrowth = 1mb
) 

修改数据库
例:修改数据库student主数据文件的大小,将主数据文件的初始大小修改为10Mb,增长方式为20%;

alter database student        
modify file                  
(                                //修改文件用modify file
	name = stu,                 //修改日志文件是modify log file
	size = 10mb,
	filegrowth =20%
) 

删除数据文件及日志文件

例:删除数据库student辅助数据文件和第二个日志文件;

alter database student
romove file stu2
go                          //注意go语句是让多条语句分别执行
alter database student
remove file stu_log2

2.模式的创建

模式定义语句如下:

CREATE SCHEMA<模式名>AUTHORIZTION<用户名>;

注意:如果没有指定<模式名>,则<模式名>隐含为<用户名>。要创建模式时,调用该命令的用户必须拥有数据库管理员权限,或者获得了数据库管理员授予的 CREATE SCHEMA 的权限。
例如:
为用户WANG定义一个学生-课程模式S-T。

CREATE SCHEMA"S-T" AUTHORIZATION WANG;

用户可以在创建模式的同时在这个模式定义中进一步创建表、视图,定义授权。
例如:
为用户ZHANG创建一个模式TEST,并且在其中定义一个表TAB。

CREATE SCHEMA TEST AUTHORIZATION ZHANG
CREATE TABLE TAB(COL1 SMALLINT,
                 COL2 INT,
                 COL3 CHAR(20),
                 COL4 NUMERLC(10,3)
                 ......
                 );

3.定义基本表

SQL语言使用 CREATE TABLE 语句来定义基本表,其格式:

CREATE TABLE <表名> (<列名><数据类型>[列级完整性约束条件]
                 [,<列名><数据类型>[列级完整性约束条件]]
                 ....
                 [,<表级完整性约束条件>]);

例如:
建立一个"学生表"Student.

CREATE TABLE Student
(Sno CHAR(9)   PRIMARY KEY,        /*列级完整性约束条件,Sno是主码*/
Sname CHAR(20) UNIQUE,               /*Sname 取唯一值*/
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);

定义两个码
如:建立学生选课表SC。

CREATE TABLE SC
(Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY(Sno,Cno),    /*主码由两个属性组成,必须作为表级完整性进行定义*/
FOREIGN KEY(Sno) REFERENCES Student(Sno),  /*表级完整性约束条件,Sno是外码,被参照表是Student*/
FOREIGN KEY(Cno) REFERENCES Course(Cno), /*表级完整性约束条件,Cno是外码,被参照表是Course*/

4.数据表查询、修改操作

1、 显示学号最后一位为1或者2或者3的学生的学号、姓名、性别年龄及院系;

select sno,sname,ssex,sdept
from student
where sno like '&[1-3]';

2、 查询所有院系不是CS、IS的男同学信息。

select all*
from student
where sdept not in('cs','is') and ssex='男';

3、 修改student表,将cs系姓名为“李咏”的学生姓名为“李勇”

update student
set sname='李勇'
where sdept='cs' and sname='李咏'

4、 将学号为“200515010”的学生信息重新设置为“王丹丹、女、20、MA”;

update student
set sname='王丹丹',ssex='女',sage=20,sdept='MA'
where sno=200515010;

5、 修改course表,将“数据处理”的学分改为3学分;

update course
set ccredit=3
where cname='数据处理';

6、 修改CS表,将选修课程“1”的同学成绩加5分;

update sc
set grade=grade+5
where cno=01;

7、 删除数据表student中无专业的学生记录;

delete
from student
where sdept is null;

8、删除数据表course中学分低于1学分的课程信息;

delete
from course
where ccredit<1;

9、按照院系降序显示所有学生的 “院系,学号、姓名、性别、年龄”等信息,其中院系按照以下规定显示:院系为CS显示为计算机系,院系为IS显示为信息系,院系为MA显示为数学系,院系为EN显示为外语系,院系为CM显示为中医系,院系为WM显示为西医系,其他显示为院系不明;

select 院系=case
     when sdept='CS' then '计算机系'
     when sdept='IS' then '信息系'
     when sdept='MA' then '数学系'
     when sdept='EN' then '外语系'
     when sdept='CM' then '中医系'
     when sdept='WM' then '西医系'
     else '院系不明'
     end,sno 学号,sname 姓名,ssex 性别,sage 年龄
 from student
      order by sdept desc;

10、查询同时选修“1”号课程和“2”号课程的所有学生的学号;

 select sno
    from sc
    where cno=1
    intersect
    select sno
    from sc
    where cno=2;

11、 查询所有院系(要求不能重复,不包括空值),并在结果集中增加一列字段“院系规模”,其中若该院系人数>=5则该字段值为“规模很大”,若该院系人数大于等于4小于5则该字段值为“规模一般”, 若该院系人数大于等于2小于4则该字段值为“规模稍小”,否则显示“规模很小”;

select  院系规模=case
             when COUNT(*)>=5 then '规模很大'     
             when COUNT(*)=4 then '规模一般'  
             when COUNT(*)>=2 and COUNT(*)<4 then '规模稍小'  
             else '规模很小'
             end,sdept 院系                
from student
group by sdept;

12、查询学生信息表中的学生总人数及平均年龄,在结果集中列标题分别指定为“学生总人数,平均年龄”;

 select count(*) 学生总人数,AVG(sage) 平均年龄
          from student

13、查询选修的课程数大于3的各个学生的选修课程数;

  select COUNT(cno) 选修课程数
    from sc
    group by sno
    having COUNT(*)>3;

14、查询IS系学生的学号、姓名、性别、年龄,并统计出IS系的学生个数;

select count(sno) as 人数
from student
where sdept='IS'
go                     
select sno,sname,ssex,sage 
from student 
where sdept='IS'
 /*本题我用的是go,也可以使用computer方法,主要区别就是server的版本了,
 08版的支持computer,12版以上就不支持了*/

15、查询每个院系的学生前两条记录,并组成新表ceshi;

select a.* into ceshi1 from student a

where Sno in (select top 2 Sno from student

where Sdept=a.Sdept

order by Sno desc)

16、查询平均成绩大于“赵菁菁”平均成绩的各个学生的学号、平均成绩;

 select sno,avg(grade) 平均成绩
 from sc 
 group by sno	
 having avg(grade)>(select avg(grade)
	                from sc
			         where sno=(select sno
				               from student
							   where sname='赵菁菁'
							   )
							   )

17、查询选修了‘数学’或者‘大学英语’的学生学号、姓名、所在院系、选修课程号及成绩;

select student.sno,sname,sdept,course.cno,grade
from student,course,sc
where student.sno=sc.sno and sc.cno=course.cno and cname='数学' or cname='大学英语';

18、查询与‘张力’(假设姓名唯一)年龄不同的所有学生的信息;

select *
from student
where sage<>(
           select sage
		   from student
		   where sname='张力');

19、按照“学号,姓名,所在院系,已修学分”的顺序列出学生学分的获得情况。其中已修学分为考试已经及格的课程学分之和;

select student.sno,student.sname,sdept,sum(course.ccredit) 已修学分
from student,sc,course
where grade>=60 and student.sno=sc.sno and sc.cno=course.cno  
group by student.sno,student.sname,sdept;

20、查找选修了至少一门和张力选修课程一样的学生的学号、姓名及课程号;

select student.sno,sname,cno
from student,sc
where cno in (
              select cno
			  from sc,student
			  where sname='张力' and student.sno=sc.sno)  /*通过student.sno=sc.sno连接*/
	        and student.sno=sc.sno;
	        /*将表student与表sc连接起来*/

21、查询只被一名学生选修的课程的课程号、课程名;

select course.cno,cname
from course,sc,student
where student.sno in(select sc.sno
                     from sc
					 group by sno
					 having count(cno)='1')
					 and student.sno=sc.sno and sc.cno=course.cno;
					 /*三表连接*/

22、使用嵌套查询出选修了“数据结构”课程的学生学号和姓名;

select sno,sname
from student
where sno=(select sno
            from sc
			where cno=(select cno
			           from course
					   where cname='数据结构'));

23、使用嵌套查询查询其它系中年龄小于CS系的某个学生的学生姓名、年龄和院系;

select sname,sage,sdept
from student
where sage< any (select sage
                 from student
				 where sdept='cs')
	   and sdept<>'cs';
	   /*<>”表示不等于*/
	   /*本题用到any方法*/

24、使用ANY、ALL 查询,列出其他院系中比WM系所有学生年龄小的学生的姓名;

select sname 姓名
from student
where sage< all (select sage
                 from student
				 where sdept='WM')
	   and sdept<>'WM'
	   /*用到all方法*/

25、使用集合查询查询选修1号课程同时选修2号课程的同学的学号与姓名;

select student.sno 学号,sname 姓名
from student,sc
where cno='01' and student.sno=sc.sno
intersect
select student.sno 学号,sname 姓名
from student,sc
where cno='02' and student.sno=sc.sno;
/*集合查询*/

5.视图创建与查询

1、创建v_CS视图,包括CS系各学生的学号、姓名及年龄,要求进行修改和插入操作时仍需保证该视图只有CS系的学生;

create view v_cs
as 
select sno,sname,sage
from XSKC.student
where sdept='cs'
with check option;;

2、创建v_CS_age20视图,包括CS系学生年龄在20岁以上的基本信息;并保证对视图文本的修改都要符合年龄大于20这个条件。

create view v_cs_age20
as 
select sno,sname,sage,ssex,sdept
from student
where sdept='cs' and sage>20
with check option;

3、创建一个视图vstu_cg,用于查看学生学号、姓名、课程和成绩信息,并用WITH ENCRYPTION加密。

create view vstu_cg
with encryption
as 
select student.sno,sname,cno,grade
from student,sc
where student.sno=sc.sno;

4、 试着向视图v_CS中插入一个新的学生记录,(‘200515026’,‘赵红平’,‘21’),是否能插入成功,原因是什么?如何修改视图才可以插入成功?

insert
into v_cs
values('200515026','赵红军','21');

不能插入,因为有with check option语句限制,插入的学生必须是
cs系的,将新建视图的限制条件去掉即可。

5、 利用视图v_CS修改学号为200515001的学生姓名为“赵青青”;

update v_cs
set sname='赵青青'
where sno='200515001';

6、 利用视图v_CS删除CS系学号为200515003的记录;

delete
from v_cs
where sno='200515003';

7、 删除视图v_CS_age20;

drop view v_cs_age20;

6.数据库的完整性约束

  1. 将数据库stu的表course的cno字段定义为主键,约束名称为cno_pk;
use stu
create table kc
(cno int constraint cno_pk primary key,
 cname char(20),
 cpno int,
 ccredit int);
  1. 为表course中的字段cname添加唯一值约束;
alter table kc
add constraint cname_uk unique (cname);
  1. 对于数据表sc的sno、cno字段定义为外码,使之与表student的主码sno及表course的主码cno对应,实现如下参照完整性:
1.删除student表中记录的同时删除sc表中与该记录sno字段值相同的记录;
2.修改student表某记录的sno时,若sc表中与该字段值对应的有若干条记
  录,则拒绝修改;
3.修改course表cno字段值时,该字段在sc表中的对应值也应修改;
4.删除course表一条记录时,若该字段在在sc表中存在,则删除该字段
  对应的记录;
5.向sc表添加记录时,如果该记录的sno字段的值在student中不存在,
  则拒绝插入;
alter table sc
add constraint sc_fk
foreign key (sno) references student(sno)
on delete cascade on update cascade,
foreign key (cno) references course(cno)
on delete cascade on update cascade

4)定义check约束,要求学生学号sno必须为9位数字字符,且不能以0开头,第二三位皆为0;

alter table student
add constraint sno_ck
check (sno like '[0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9] [0-9]' and sno<>'0_ _ _ _ _ _ _ _' and sno like '_00_ _ _ _ _ _')

5)定义stu数据库中student表中学生年龄值在16~25范围内;

CREATE TABLE student
    (Sno  char(9) Primary Key,
	Sname char(8),
	ssex  char(2),
    Sage  smallint,
    Sdept  varchar(20),
	CHECK(SAGE>=16 AND  (   SAGE<=25) ))

6)定义stu数据库student表中学生年龄值默认值为20;

alter table student
add constraint sage_default
default 20 for sage;

7) 修改student表学生的年龄值约束可以为15~30范围内;

alter table student
add constraint sage_ck
check (sage between 15 and 30)

8) 删除表course中字段cname的唯一值约束;

ALTER TABLE course
	Drop constraint cname_uk

7.触发器

  1. 为表course建立一个 INSERT触发器,当插入的新行中课程学分(ccredit)的值不是1~6时,就激活该出发器,撤销该插入操作,并使用RAISERROR语句返回一个错误信息。
create trigger course_insert on course for insert
as 
declare @pr_ccredit char(4)
select @pr_ccredit=ccredit from inserted
if @pr_ccredit>7 or @pr_ccredit<1
 begin
 raiserror('不能插入',16,10)
 rollback tran  
 end

2)为course表再创建一个UPDATE触发器,当更新了某门课程的课程号信息时,就激活该触发器级联更新sc表中相关的课程号信息,并使用PRINT语句返回一个提示信息。

create trigger cno_update on course
after update
as
begin
declare @old_cno char(9),@new_cno char(9)
select @old_cno=cno from deleted
select @new_cno=cno from inserted
update sc set cno=@new_cno where cno=@old_cno
 end

3)为student表创建DELECT触发器,在删除中的一条记录的同时将sc表中的相应记录也删除。

create trigger sno_delete on student
after delete
as
begin
delete from sc where sno in(select sno from deleted)
 endv

4)创建INSTEAD OF触发器,当向sc表中插入记录时,先检查sno列上的值在student中是否存在,如果存在执行插入操作,如果不存在则提示“该学生不存在”。

create trigger ttble on sc
instead of
insert 
as
		declare @pr_sno char(9)
		select @pr_sno = sno from inserted
		if @pr_sno not in(select sno from student)
		begin
			raiserror('该学生不存在!',6,10)
			rollback tran
	end

5)比较约束与触发器的执行顺序。(在一个表中创建CHECK约束和触发器,然后向表中插入一条不符合约束和触发器的记录,察看谁先发生作用。)

Insert 语句执行时首先验证约束,同时约束本身也有先后顺序
  1 、验证非空约束
  2 、验证主键约束
  3 、验证唯一性约束
再次验证相关 Check
最后执行触发器,如果触发器中也必须保证不违反相关约束和 Check

补充:

1.变量的使用
(1)创建局部变量@xh(char(9))并使用set将student表中“李勇”的学号字段赋给该变量,然后使用select显示变量的值;

declare @xh char(9)
set @xh=(select sno
    from student
    where sname='李勇')
select @xh
go
   

(2)计算学生信息表student中学生最高年龄和最低年龄之差,并使用select将结果赋值给@cz,并使用print显示变量的值。

declare @cz float(5)
select @cz=MAX(sage)-MIN(sage) from student
print @cz


2.应用内置函数

(1)求course表中课程号为“03”的课程名称的长度,并在消息提示框中输出结果。结果格式为:“03号课程名称的长度为:**”。提示:使用CONVERT函数。

declare @int int
select @int=len(cname)
       from course
	   where cno=3
print('3号课程名称长度为:'+CONVERT(varchar(4),@int))

(2)使用字符串串联运算符“+”,将student表中的所有字段串联在一起用一个“学生信息”字段显示出来。

select sno+sname+sdept+CONVERT(varchar(4),sage)+ssex as 学生信息
from student

3. 流程控制语句

(1)判断student表中是否存在编号为2005150026的学生,如果存在,则显示该学生基本信息;若不存在,则显示“查无此人”。

if exists(select * from student
where sno='2005150026')
begin
select * from student
where sno='2005150026'
end
else
print('没有此人')

(2)查询学号为“200515002”的学生的平均分是否超过了85分,若超过则输出“XX(学生姓名)考出了高分”,否则输出“XX(学生姓名)考的一般”。

declare @int int,@sum int,@name char(15)
set @int=85
select @sum=AVG(grade)
     from sc
	 where sno=200515002  
select @name=sname 
        from student
		where sno=200515002
if  @sum>@int
 print(@name+'考出了高分')
 else
 print(@name+'考的一般')

4. 定义函数

(1)定义一个函数CHECK_SNO实现如下功能:对于一个给定的sno值,查询该值在sc表中是否存在,若存在则返回0,否则返回-1。

create function check_sno(@sno char(20))
returns integer as
begin
    declare @bool char(20)
	if exists(select sno from sc where @sno=sno)
	      select @bool =0
	else
	    select @bool = -1
	return @bool
end

(2)写一段T-sql程序调用上述函数。当向sc表插入一行记录时,首先调用函数CHECK_SNO检索该记录的sno值在表student中是否存在对应值,若存在,则将该记录插入记录(‘200515023’,’02’,75)到sc表中。

DECLARE @num int

SELECT @num=dbo.CHECK_sno('2')

   IF @num=0

      INSERT sc

    VALUES('200515023','02',75)
    go

(3)定义一函数,按系别统计当前所有学生的平均年龄,

CREATE FUNCTION aver_age(@sdept char(2))   
RETURNS int  AS  
BEGIN 
	declare @aver int
	select @aver =(select avg(sage) from student where sdept=@sdept)
	Return @aver
END

并调用该函数求出“CS”系学生的平均年龄。

declare @sdept char(2)
select @sdept='CS'
select dbo.aver_age(@sdept)

5.存储过程

(1)创建一个无参存储过程pr_StuScore,查询以下信息:班级、学号、姓名、性别、课程名称、考试成绩。

create proc pr_StuScore  
as
select *  
from sc,student
go

(2)创建一个带参数的存储过程pr_StuScoreInfo2,该存储过程根据传入的学生编号和课程名称查询以下信息:班级、学号、姓名、性别、课程名称、考试成绩。

create proc pr_StuScoreInfo2
@cname char(4),@sno int
as
select *
from student,sc,course
 where course.cname=@cname and student.sno=@sno
go

(3)创建一个带参数的存储过程pr_xxscore,该存储过程根据传入的学生编号和课程号,并通过变量输出该学生的课程成绩。

create proc pr_xxscore
@cname char(4),@sno int,@gread int
as
select @gread=sc.grade
from student,sc,course
 where course.cname=@cname and student.sno=@sno
 print(@gread)
go

(4)创建存储过程,通过给定两个学生的学号,比较两个学生的年龄,若前者比后者高就输出0,否则输出1。(调用时比较200515001号和200515002号的年龄)。

create procedure compa  @sno1 char(10),@sno2 char(10),@result int output
as
begin
    declare @sage1 int,@sage2 int
	set @sage1=(select sage  from student where sno=@sno1)
	set @sage2=(select sage from student where sno=@sno2)
	if @sage1>@sage2
	    set @result=0
	else
	    set @result=1
end

执行操作:

exec compa '200515001','200515002' ,@result output
select @result

(5)编写带参数的存储过程pr_cavg,根据传入的课程名称统计该课程的平均成绩。

create  proc pr_cavg @cname char(6),@avg float
as
set @avg=(select AVG(grade)
          from sc,course
		  where sc.cno=course.cno  and  course.cname=@cname)

go

(6)创建一存储过程pr_age,用于统计某年龄段所有学生的学号、姓名及所选课程信息。

create proc pr_age
(@maxage int,
@minage int)
as
select a.sno,sname,b.cno,cname,grade
from student a,course b,sc c
where a.sno=c.sno and b.cno=c.cno and sage<@maxage and sage>@minage 

执行操作:

exec pr_age 21,15

(7)创建一个添加学生记录的存储过程stduentadd,用来给student表添加一条记
(‘200515028’,‘徐小明’,‘男’,24,‘CS’)

create proc pr_studentadd @sno char(10),@sname char(50),@ssex char(2),@sage int,@sdept char(10)
as
begin
set @sno='200515028'set @sname='徐小明' set @ssex='男' set @sage=24 set @sdept='CS'
insert into student(sno,sname,ssex,sage,sdept)values(@sno,@sname,@ssex,@sage,@sdept)
end 
go

==================
作者:@2000亿颗星星

文章:https://mp.csdn.net/mdeditor/90177902#

转载请注明出处哦!:https://mp.csdn.net/mdeditor/90177902#

你可能感兴趣的:(数据库)