SQL Server脚本练习

最近正在准备,计算机四级 的数据库,做了一些关于SQL语句的练习,包括数据库的建立,表的建立,查询插入,触发器的一些练习,只是一些很简单的练习并不深入原理,也不深入展开叙述,仅仅作为一些基础的SQL 命令。

CREATE DATABASE StudentDB
ON primary
(
	name='StudentDB',--逻辑名和DB名称保持一致
	filename='G:\Desktop\jh\DB\Data\StudentDB.mdf',--物理名称
	size=3mb,
	maxsize=unlimited,
	filegrowth=1mb
),
(
	name='StudentDB1',--逻辑名和DB名称保持一致
	filename='G:\Desktop\jh\DB\Data\StudentDB1.ndf',--物理名称
	size=3mb,
	maxsize=unlimited,
	filegrowth=1mb
),--辅助数据文件
(
	name='StudentDB2',--逻辑名和DB名称保持一致
	filename='G:\Desktop\jh\DB\Data\StudentDB2.ndf',--物理名称
	size=3mb,
	maxsize=unlimited,
	filegrowth=1mb
)
log on
(
	name='StudentDB_log',--逻辑名和DB名称保持一致
	filename='G:\Desktop\jh\DB\Data\StudentDB_log.ldf',--物理名称
	size=1mb,
	maxsize=3gb,
	filegrowth=10%--以源文件的10%增长
)
--修改
alter database StudentDB --alter修改database对象
modify file--修改file对象
(
name=StudentDB,--修改对象的逻辑名称
size=5mb)
--添加新的辅助文件到新的文件组
alter database StudentDB
add filegroup GData
go--批处理
alter database StudentDB
add file
(
	name='StuDB03',
	filename='G:\Desktop\jh\DB\Data02\StuDB03.ndf'
)
to filegroup GData
--删除辅助文件StuDB03
alter Database StudentDB
remove file StuDB03--删除数据库辅助文件
--删除数据库
drop database StudentDB--drop专门用来删除数据库,表,图
--分离与附加
--分离数据库
exec sp_detach_db StudentDB--分离的意义就在于可以在数据库使用的时候
--将数据文件进行分离,进行操作
--EXEC代表执行, sp_detach_db是存储过程,dbname是数据库名称:
--只是将数据库从服务器上分离出去,
--其原有的日志文件和数据文件还在原有位置进行保存;


--附加数据库
create database StudentDB
on primary
(
	name='StudentDB',
	filename='G:\Desktop\jh\DB\Data\StudentDB.mdf'
)
for attach
--将数据文件和数据库相分离,可以将数据文件移植到别的地方
--只有分离的数据库才能附加,
--分离后的数据库不能再正常读取,
--只有附加后才能读取;
--数据库架构
--指的是数据库中的一个名字空间
--它包含一组表、视图和存储过程等命名对象
--就是一个数据库用户所拥有的数据库的对象
use StudentDB
--创建架构
create schema my
--删除架构
drop schema my
-------/*********************************************************/
--有关表的操作
--创建数据表
use StudentDB
create table Stu_Info
(
	Stu_NO varchar(20) primary key not null,
	Stu_Name varchar(10),
	Stu_Sex varchar(6),
	Stu_Birthday date,
	Stu_Address nvarchar(200)
)
--varchar(n)
--长度为 n 个字节的可变长度且非 Unicode 的字符数据。
--n 必须是一个介于 1 和 8,000 之间的数值。
--存储大小为输入数据的字节的实际长度,而不是 n 个字节。

--nvarchar(n)
--包含 n 个字符的可变长度 Unicode 字符数据。
--n 的值必须介于 1 与 4,000 之间。
--字节的存储大小是所输入字符个数的两倍。
alter table dbo.Stu_Info
add Stest int not null--增加Stest列数据类型为int并且不空
--修改列的数据类型
alter table dbo.Stu_Info
alter column Stest varchar(20)--column是列的意思,修改列
--删除列
alter table dbo.Stu_Info
drop column Stest
--添加列
alter table dbo.Stu_Info
add Stest varchar(20)--列名+数据类型
--删除数据表
drop table Stu_Info--物理删除,一旦删除不能恢复。

---------------*********************************************-
--创建分区表
--表数据就会按照你指定的规则分放到不同的文件里,
--把一个大的数据文件拆分为多个小文件,
--还可以把这些小文件放在不同的磁盘下由多个cpu进行处理。
--这样文件的大小随着拆分而减小,还得到硬件系统的加强,
--自然对我们操作数据是大大有利的。



--第一步创建分区函数
create partition function YearOrderFuc(int)
as range left for values('2007','2009')--左分区


--第二步创建分区方案
create partition scheme YearOrderScheme
as partition YearOrderFuc--根据那个分区函数,分的区,文件组
to
(
	[primary],fgroup1
)
--最后根据分区方案创建分区表
create table Tb_StudentInfo
(
	StdInfoID int identity(1,1) not null,
	StdName varchar(20) not null,
	StdYear int not null
)
on YearOrderScheme(StdYear)
alter DataBASE StudentDB
add filegroup fgroup1
--****************************
--视图,一种虚表,只供查询,不更新
use StudentDB
create table CourseInfo
(
	CourseInfoID int identity(1,1) not null,
	CourseName varchar(20) not null,
	CourseSpace varchar(20) not null,
	CourseTeacherName varchar(30) not null,
)
create table TeachInfo
(
	CourseInfoID int identity(1,1)not null,
	TeacherInfoID int not null,
)
create table TeacherCourse
(
	TeacherID int identity(1,1) not null,
	CourseInfoName varchar(20)not null,
	TeachInfoName varchar(30)not null,
	CourseInfoID int not null
)
create view View_TeacherCource
(
	课程名称,老师姓名
)
as
select CourseInfoName,TeachInfoName
from CourseInfo a join TeachInfo b
join TeacherCourse c
on a.CourseInfoID=b.CourseInfoID 
on b.TeacherInfoID=c.TeacherInfoID


--------------------********************
--约束
--NOT NULL约束
use StudentDB
create table StudentInfo
(
	StudentID int identity(1,1)not null,
	StuName varchar(20)not null,
	StuAge int
)
--default约束
--创建班级信息表,创建的系部默认软件学院,人数默认35
create table ClassInfo
(
	ClassId int not null,
	ClassInDep varchar(20) not null default('软件学院'),
	ClassCount int not null default(35)
)
--增加约束
alter table ClassInfo
add constraint df_ClassInfoID default(1001)for ClassId--注意要给约束起个名字,一般用df开头,缺省约束
--唯一约束,所以字段取值唯一,允许null的出现,但是不允许两个NULL
create table StudentInfo2
(
	StdID int not null,
	StdInfo varchar(20)not null unique,
)
--增加约束
alter table StudentInfo2
add constraint uk_stdid unique(StdID)
------------------------*****************************
use StudentDB
create table dbo.StudentCourse1
(
	StdId int identity(1001,1)not null,
	StdName varchar(20) not null unique,
	CourseID int not null,
	CourseName varchar(30)not null,
	TeacherID int not null,--只能一个字段自增
	TeacherName varchar(20)not null
)
use StudentDB
create table dbo.TeacherCourse1
(
	TeacherID int not null,
	TeacherName varchar(20)not null,
	CoureseName varchar(30)not null
)
alter table dbo.TeacherCourse1
alter column CoureseName varchar(30)
select * from information_schema.table_constraints;
-------------------------*****************************
--insert语句的使用
--单条语句的使用
use StudentDB
insert StudentCourse1
values('jack',25,'Chinese',30,'Tom')--有自增的不要插入数据
--插入多次语句
use StudentDB
insert StudentCourse1
values('tiki',25,'Chinese',30,'Tom')
--插入部分数据
insert dbo.TeacherCourse1(TeacherID,TeacherName)
values(18,'Tom')
--创建一个新表,新表中的数据部分来自之前的旧表
--例如TeacherCourse1表中将ID小于10的新建一个表
create table dbo.TeacherCourse2
(
	TeacherID int not null,
	TeacherName varchar(20)not null,
	CoureseName varchar(30)not null
)
insert into dbo.TeacherCourse2--into可以省略,但是不推荐
select TeacherID,TeacherName,CoureseName
from dbo.TeacherCourse1
where TeacherID<=10

------------------------------------********************
--update更新语句
--将江河更新为姜赫在StudentInfo表中
update StudentInfo
set StuName='姜赫'
where StuName='江河'

--delete语句的使用
--和select语句基本一样
--第一直接删除
--第二基于其他表的删除,from on语句
--第三删除所有表中的内容,需要用一个批处理 go
--或者truncate语句都可以删除,但是truncate效率高,使用的资源比较少
--删除表的时候一定要确保表没有在使用

--***********************************
--查询语句
use StudentDB
select *from dbo.StudentCourse1
--*号代表所以的内容,可以将*号换成其他想查询的内容
use StudentDB
select distinct StdId from dbo.StudentCourse1
--消除重复的值
select top 8 StdId from 
--查询前8条信息
select top 8 percent StdId from dbo.StudentCourse1
--查询前8%的信息
--取行的中文名字
use StudentDB
select StdId as 学号 from dbo.StudentCourse1
select 学号=StdId from dbo.StudentCourse1
--查询并且排序,排序默认升序
--desc降序
--asc升序
select StdId,StdName,CourseID,CourseName from dbo.StudentCourse1
where StdId>=20
order by StdId
select StdId,StdName,CourseID,CourseName from dbo.StudentCourse1
where StdId>=20
order by StdId desc
--like 用来做模糊查询,还有%符号
--聚合函数
--聚合函数:
--SQL中提供的聚合函数可以用来统计、求和、求最值等等。

--分类:
--–COUNT:统计行数量
–--SUM:获取单个列的合计值
–--AVG:计算某个列的平均值
–--MAX:计算列的最大值
–--MIN:计算列的最小值
select COUNT(*)from dbo.StudentCourse1
select MAX(StdId)from dbo.StudentCourse1


--****************************************
--连接查询
--内连接
--外连接
--查询结果的交并差结果运算
--1、内联接(典型的联接运算,使用像 =  或 <> 之类的比较运算符)。
--包括相等联接和自然联接。     
--内联接使用比较运算符根据每个表共有的列的值匹配两个表中的行。   
    
--2、外联接。外联接可以是左向外联接、右向外联接或完整外部联接。     
--在 FROM子句中指定外联接时,可以由下列几组关键字中的一组指定:     

--1)LEFT  JOIN或LEFT OUTER JOIN     
--左向外联接的结果集包括  LEFT OUTER子句中指定的左表的所有行,
--而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,
--则在相关联的结果集行中右表的所有选择列表列均为空值。       

--2)RIGHT  JOIN 或 RIGHT  OUTER  JOIN     
--右向外联接是左向外联接的反向联接。将返回右表的所有行。
--如果右表的某行在左表中没有匹配行,则将为左表返回空值。       
--3)FULL  JOIN 或 FULL OUTER JOIN
--完整外部联接返回左表和右表中的所有行。
--当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。
--如果表之间有匹配行,则整个结果集行包含基表的数据值。   
    
--3、交叉联接   
--交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合。
--交叉联接也称作笛卡尔积。
----*********************************************************
--总结:                                         ************
--内连接                                       **************
--说明:组合两个表中的记录,返回关联字段相符的记录,*********
--也就是返回两个表的交集(阴影)部分。           ************
--左连接,左表所有内容和两个表的交集             ************
--右连接,右表所有内容和两个表的交集             ************
--某行在另一个表中没有匹配行时则另一个表的选择列表列包含空值*
-----------**************************************************
--内连接
use StudentDB
select StdId,StdName,CourseID
from dbo.StudentCourse a join dbo.StudentCourse1 b
on a.StdId=b.StdId
--左外连接
use StudentDB
select StdId,StdName,CourseID
from dbo.StudentCourse a left join dbo.StudentCourse1 b
on a.StdId=b.StdId
--右外连接
use StudentDB
select StdId,StdName,CourseID
from dbo.StudentCourse a right join dbo.StudentCourse1 b
on a.StdId=b.StdId
--完全外连接
use StudentDB
select StdId,StdName,CourseID
from dbo.StudentCourse a full join dbo.StudentCourse1 b
on a.StdId=b.StdId
------------查询结果的运算,交并差运算
select StdId from dbo.StudentCourse
union
select Stu_Name from dbo.Stu_Info
--以第一个列名为准
--交运算intersect
--差运算except
---------------***********************
use StudentDB
create table dbo.StudentInfomation
(
	StuId varchar(20)unique not null ,
	sex varchar(10)default('boy'),
	age int not null,
)

--子查询
--子查询就是指的在一个完整的查询语句之中
--嵌套若干个不同功能的小查询,
--从而一起完成复杂查询的一种编写形式
--查询结果做派生表
--例如,查询女学生,年龄大于18的ID
select StuId from(
select * from dbo.StudentInfomation
where sex='girl')as t--必须取个别名,否则无法引用
where t.age>=18
--子查询用作表达式
--使用比较运算符的子查询
--使用ALL,SOME或ANY的子查询
--使用IN 或NOT IN 的子查询
--使用EXISTS 和NOT EXISTS的子查询




--子查询要从底层一层一层的开始查询

--************************************开窗函数
--普通的聚合函数聚合的行集是组,开窗函数聚合的行集是窗口。
--因此,普通的聚合函数每组(Group by)只返回一个值,
--而开窗函数则可为窗口中的每行都返回一个值。
--简单理解,就是对查询的结果多出一列,这一列可以是聚合值,
--也可以是排序值。





--**************存储过程
-- 存储过程(Stored Procedure)是一种在数据库中存储复杂程序,
--以便外部程序调用的一种数据库对象。

--存储过程是为了完成特定功能的SQL语句集,
--经编译创建并保存在数据库中,
--用户可通过指定存储过程的名字并给定参数(需要时)来调用执行。

--存储过程思想上很简单,就是数据库 SQL 语言层面的代码封装与重用。

--优点

 --   存储过程可封装,并隐藏复杂的商业逻辑。
  --  存储过程可以回传值,并可以接受参数。
 --   存储过程无法使用 SELECT 指令来运行,因为它是子程序,与查看表,数据表或用户定义函数不同。
  --  存储过程可以用在数据检验,强制实行商业逻辑等。

--缺点

--    存储过程,往往定制化于特定的数据库上,因为支持的编程语言不同。当切换到其他厂商的数据库系统时,需要重写原有的存储过程。
 --   存储过程的性能调校与撰写,受限于各种数据库系统。
 
 
 --------*********************----------------------------*--*-*-*
 --创建存储过程
 --可以将procedure可以简写成proc
 create procedure ShowTeacherCourese--起一个别名
 as--存储过程的内容
 create table StudentInfomation1
 (
	 Stdname varchar(20),
	 StdId int not null
 )
 ShowTeacherCourese--这样执行
 execute ShowTeacherCourese
 exec ShowTeacherCourese
 --以上三种方式执行
 --*************
 --修改存储过程
 alter procedure ShowTeacherCourese
 as
	
	--修改存储过程
exec ShowTeacherCourese--执行存储过程
--删除存储过程直接用drop procedure 存储过程名称
--******************重点
 --参数化存储过程
 --带输入参数,输出参数,Return返回数据
 create procedure SELE_NAME
 @name varchar(20)
 as
	if @name is null
	begin
		print '为查询到该学生的信息,将返回所以学生信息'
		select *from dbo.StudentCourse1
	end
	else
	begin
		select Stdld as '学号',StdName as '学生姓名',CourseID as '课程号',
		TeacherID as '教师号码',TeacherName as '教师姓名' from dbo.StudentCourse1 a
		where a.StdName=@name
	end
alter proc SELE_NAME
@name varchar(30)
as
	if @name is null
	begin
		print '为查询到该学生的信息,将返回所以学生信息'
		select StdId as'学号' from dbo.StudentCourse1
	end
	else
	begin
		select  StdId as '学号' from dbo.StudentCourse1 a
		where a.StdName=@name
	end
use StudentDB
execute SELE_NAME null
--输出参数
create procedure SELE_StdID
(
	@STD_ID int output,
	--设置过程
)
declare @ID int
execute SELE_StdID @ID output--写上OUTPUT
select @ID

--------*********************

--触发器,SQL后台编程
--触发器类似于函数和过程,
--它们都是具有声明部分、执行部分和异常处理部分的程序实体单元。
--触发器必须在数据库中以独立对象的身份存储。
--触发器是在事件发生时隐式地运行的,不能接收参数,不能被调用。
--触发事件包括INSERT、UPDATE或DELETE,
--触发时机有两BEFORE和AFTER,
--可以在触发事件之前也可以在触发事件之后发生。
--************************************************************
--DML触发器
--DDL触发器
--修改和删除触发器
-----*************************************
--DML触发器, INSTEAD OF触发器和AFTER触发器
--从功能来看,INSTEAD OF触发器用来替换实际的数据修改操作,
--而AFTER触发器用来在实际操作完成后进行后续操作。
--例如对于DELETE操作,
--如果我们期望只修改数据状态来标示数据已被删除而不是将数据从表中删除,
--那么我们可以使用INSTEAD OF触发器来实现;前触发器
--如果我们期望在删除数据后在其他表记录删除操作的发生时间,
--那么我们可以使用AFTER触发器来实现。

--
use StudentDB
--insert触发器,插入之前存在就不插入,反之进行插入动作
create trigger trig_InsertTableInfo
on dbo.StudentCourse1
after insert
as
begin transaction--事务
if exists (select *from dbo.StudentCourse1)
begin
	raiserror('数据一致性',16,1)--报错
	rollback transaction
end
else
begin
	commit transaction
end
--update触发器
--更新分成两步,先删除原先的数据,后存放删除之后的数据
--delete逻辑表存放删除的数据
--insert逻辑表存放更新的数据
create trigger trig_Update
on dbo.StudentCourse1
after update
as
if UPDATE(StdId)
begin
	update dbo.StudentCourse1
	set StdId=(select StdId from deleted)
	where StdId=(select StdId from inserted)
end


--delete触发器,删除冗余信息,保证数据库的正常运行
create trigger trig_dele
on dbo.StudentCourse1
after delete
as
begin
	declare @STDID int
	SELECT @STDID= deleted.StdId from deleted
	delete dbo.Stu_Info
	where StdId=@STDID
end
-------------*******
--DDL触发器是由修改数据库对象的 DDL 语句
--(如以 CREATE、ALTER 或 DROP)激发。

--DDL 触发器作用:
--DDL 触发器主要用于防止对数据库架构、视图、表、存储过程
--等进行的某些修改。
--DDL 触发器事件:
--DDL 触发器在创建用来监视并响应该数据库或服务器实例中的活动的
--事件通知时,可以指定相应事件类型或事件组。
-- DDL触发器支持BEFORE和AFTER事件触发器,
--并在数据库或模式级运行。
--通常,DDL触发器用于监控数据库中的重要事件。
--有时用它们来监控错误代码。
--错误代码可能会执行破坏数据库或使数据库不稳定的活动。
--更常见的情况是:在开发、测试和stage系统中用它们来了解和监控数据库活动的动态。
--当监控GRANT和REVOKE权限语句时,它们也是有效的安全工具。
--函数,默认返回单值
--表值函数,返回一个表
create Function Functi01(@Name varchar(20))
return table 
as 
begin
end


--------------------------------------***
--游标的使用
-- 游标是邪恶的!
--在关系数据库中,我们对于查询的思考是面向集合的。
--而游标打破了这一规则,游标使得我们思考方式变为逐行进行
--对于类C的开发人员来着,这样的思考方式会更加舒服。
--   我个人认为存在既是合理.归结来说,学习游标原因我归纳为以下2点

--- 1.现存系统有一些游标,我们查询必须通过游标来实现

  --  2.作为一个备用方式,当我们穷尽了while循环,子查询,
  --临时表,表变量,自建函数或其他方式扔来无法实现某些查询的时候,
  --使用游标实现。
  -- 在T-SQL中,游标的生命周期由5部分组成
--1.定义一个游标
--2.打开游标
--3.使用游标
--4.关闭游标
--5.释放游标
---************************************




--安全管理
--创建新的用户
create login teachers
with password ='123',
default_database=[master],
check_expiration=on,
check_policy=on

--修改密码
alter login teachers
with password ='1234'--没有逗号
old_password='123'
--禁用账号登陆
alter login teachers enable--账户启用
alter login teachers disable--账户禁用
drop login teachers--账户删除

--创建teacher登陆名,创建teacheruser用户名,两者关联
create login teacher
with password='123456',
default_database=[master]
go
create user teacheruser
for login teacher

--修改用户名
alter user teacheruser
with name=teacheruser2

--拥有架构的用户不能删除

--备份与恢复

猜你喜欢

转载自blog.csdn.net/weixin_41066584/article/details/87291866
今日推荐