您的位置:首页 > 数据库

Sql Server基础知识总结

2013-09-04 23:19 459 查看
大半夜的无聊,翻着电脑里面的资料,发现了毕业的时候自己对Sql Server基础知识的总结,细细的看看还是很有价值的,贴出来和大家分享。

 

--==================================SQL Server身份验证模式、架构、登录名、角色、权限====================================---
go
---例句:为数据库GameCardSae_1创建用户自定义角色
---语法:sp_addrole [@rolename =] <'角色名'> [,[@ownername =] <'所有者'>]
exec sp_addrole 'GameCardDbManager'
---例句:为GameCardDbManager角色添加权限
grant select on UserInfo to GameCardDbManager
---例句:向角色中添加用户
exec sp_addrolemember GameCardDbManager,tigger
---例句:从角色中删除用户
exec sp_droprolemember GameCardDbManager,tigger
---例句:删除角色
exec sp_droprole GameCardDbManager
go
----***登录名:服务器的实体,使用登录名只能进入服务器,但不允许访问服务器中的数据库资源。
----***用户名:登录对象在数据库中的映射,可以对用户对象进行授权,提供对数据库中的访问权限。默认数据库中包含两个用户:dbo和guest
----***注:登录名被指定为某数据库的用户时,则具有访问该数据库的权限。再为用户设置具有的架构、角色及安全对象等一些操作权限,此时该登录名才具有对该数据库的相应的操作操作权限。

--======================================触发器和游标============================================---
go
if exists(select * from sysobjects where name = 'test_table')
drop table test_table
go
create table test_table
(
id int identity primary key,
userName varchar(20)
)
go
--***SQL Server提供两种主要机制来强制使用业务规则何和数据完整性:约束何触发器。其中触发器是特殊的存储过程,可在执行事件时自动执行,而存储过程是通过名字被调用的。
--***SQL Server包含三种类型的触发器:DDL触发器、DML触发器及登陆触发器:
--		1.DDL触发器当服务器或数据库中发生数据定义语言(DDL)事件时将调用DDL触发器,DDL触发器事件主要以关键字 创建create、修改alter、删除drop、授权grant、否定deny、撤消revoke、开头的T-SQL语句(执行DDL式操作的系统存储过程也可以激发DDl触发器)
--			**DDL触发器的作用可以归纳为三点:a.防止对数据库架构进行某些修改。b.希望数据库中发生某种情况以响应数据库架构中的更改。c.需要记录数据库架构中的更改或事件。
--		2.DML触发器 当数据库中发生数据操作语言(DML)事件时将调用DML触发器。DML事件包括在指定表或视图中修改数据的insert语句、update语句及delete语句。
--			**DML触发器的主要有以下四个作用:a.可通过数据库中的相关表实现级联更改。b.可以防止恶意或错误insert、update以及delete操作,并强制执行此ckeck约束定义的限制更为复杂的其他限制。与check约束不同,DML触发器可以应用其他表中的约束。c.可以评估数据修改后表的状态,并根据该差异采取措施。d.一个表中的多个同类触发器(insert、update及delete)允许采取多个不同的操作来响应同一个修改语句。
--			**DML触发器可以分为两个大类型:after触发器和instead of触发器。在执行了insert、update及delete语句操作之后执行after触发器。instead of 触发器支持基于多个基表的视图,主要优点是可以使不能更新的视图支持更新。
--		3.登陆触发器是响应logon事件而激发的存储过程。在登陆用户身份验证之后,用户会话实际建立之前出发,如果身份验证失败,则不会触发。

--***DDL触发器语法:
--		create trigger trigger_name on {all server | database}
--		{for | after} {event_type}
--		as {sql_body}
--			*all server指将DDL触发器的作用域应用于当前服务器。database指将DDL触发器的作用域应用于当前数据库。
--			*event_type指将导致激发DDL触发器的Transact-SQL语言事件。
--			*sql_body值触发后的操作
--			*指定for与指定after相同。

--例句:创建DDL触发器 当删除一个表时,激发触发器打印出一条消息
if exists(select * from sys.triggers where name = 'safety' and parent_class = 0)
drop trigger [safety] on database
go
create trigger [safety] on database for drop_table,alter_table
as
print '禁止修改数据库表!'
rollback
go
---测试触发器
if exists(select * from sysobjects where name = 'text_table')
drop table text_table
go
---禁用触发器
disable trigger [safety] on database
go
--启用触发器
enable trigger [safety] on database
go

--***DML触发器语法
--		create trigger trigger_name on {table | view} {for | after | instead of}
--		{insert,update,delete}
--		as   {sql_body}
--		*table|view 指定对其执行DML触发器的表或视图,instead of可以对视图和表执行触发器,after只能定义在表上。
--		*update,delete,insert 指的是激发触发器的操作

--		**注:每个触发器都有inserted和deleted两个特殊的表。这两个表是逻辑表,由系统管理,驻留在内存中。当执行insert、update、delete操作时这两张表用于记录操作前何操作后的记录副本

--例句:创建DML触发器  当对表中的数据进行操作时触发此触发器
if exists(select * from sys.objects where name = 'UpgradeMeneber' and type ='tr')
drop trigger UpgradeMeneber
go
create trigger UpgradeMeneber on UserInfo for update
as
declare @scoreSum int = 0
declare @userId varchar(20)
declare @upgradeScore int
declare @upgradeMemberId int
select @upgradeMemberId = MemberTypeId,@userId = UserId from inserted  --从Inserted中查询增加积分的用户信息的id
if(@upgradeMemberId != 1)  --判断用户是否是普通会员
begin
return
end
select @upgradeScore = UpgradeStandar from memberType where ID = 1  --获取升级积分的标准
select @scoreSum = sumscore from userInfo where UserId = @userId
if(@scoreSum >= @upgradeScore)  --如果积分达到积分标准时,升级用户会员
begin
update UserInfo set MemberTypeId = 2 where UserId = @userId
end
go
---测试触发器
update UserInfo set SumScore += 37000 where UserId = 'jinchengwu'
go

--例句:创建instead of触发器

----创建视图,用于演示触发器删除视图操作---
if exists(select * from sysobjects where name = 'vw_test')
drop view vw_test
go
create view vw_test
as
select * from dbo.test_table
go
if exists(select * from sys.objects where name = 'InsteadOfDemo')
drop trigger InsteadOfDemo
go
create trigger InsteadOfDemo on vw_test instead of delete
as
delete test_table where id = (select id from deleted)
go
---演示触发器--
delete dbo.vw_test where id = 1
go
--		**注:instead of支持操作视图,例如对视图执行删除操作,而实质删除视图的操作是在触发器的代码体重编写,删除视图对应的表

--***游标:游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力。我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许用户对指定位置的数据进行处理。
--***游标的扩展结果处理方式:
--		1.允许定位在结果集的特定行。
--		2.从结果集的当前位置检索一行或一部分。
--		3.支持对结果集中当前位置的行进行数据修改
--		4.为由其他用户对显示在结果集中的数据库数据所做的更改提供不同级别的可见性支持。
--		5.提供脚本、存储过程和触发器中用于访问结果集的数据的T-SQL语句。
--***SQL Server支持两种请求游标的方法:
--		1.Transact-SQL语句。
--		2.数据库应用程序接口。
--***SQL Server支持的API服务器游标类型
--		1.静态游标		2.动态游标		3.只进游标		4.由键集驱动的游标
--***SQL Server支持三种游标的实现:
--		1.T-SQL语句。基于declare cursor语法,主要用在T-SQL脚本、存储过程和触发器中。
--		2.API服务器游标。支持Ole DB、DB-Library和Odbc的API游标函数。
--		3.API客户端游标。由Ole DB、DB-Library及Odbc和实现ADO API的DLL在内部实现。
--		注:1、2均为服务器段游标。
--***服务器游标相对于客户端游标的优势:
--		1.性能高。   2.更精确的定位更新。		3.客户端内存使用更小。		4.可以有多个活动语句。
--***游标的类型:
--		1.只进游标(fast_forward):只进游标不支持滚动,它只支持游标从头到尾按顺序提取。
--		2.静态游标(static):静态游标的完整结果集在游标打开时建立在系统数据库tempdb中,静态游标总是按照游标打开时的原始数据集显示结果集。
--		3.键集驱动游标(KeySet):键集驱动游标在游标打开时,游标中的成员和行的顺序是固定的。对非键集列中的数据值所作的更改是在用户滚动游标时是可见的。但在游标外对于数据库中插入的数据,在游标中是不可见的,除非关闭并重启打开游标。
--		4.动态游标(dynamic):动态游标与静态游标是相对的。滚动游标时,动态游标反应结果集中所有更改。
--			注:客户端游标只支持静态游标和只进游标
--***T-SQL游标创建的五个步骤:
--		1.创建游标		2.打开游标		3.提取数据行		4.关闭游标		5.释放游标

--例句:创建游标,遍历用户信息表中的每一行信息

---创建游标。declare cursor_name cursor [local | global] [forward only|scroll] [static|ketset|dynamic|fast_ward] [read_only|scroll_locks|optimistic] for sql_statement
-----local指定游标的作用域是在创建它的存储过程或是触发器中,当存储过程或触发器终止后,游标被隐式释放。
-----global指定游标的作用域是全局的,在任何存储过程或触发器中都可以引用
-----forward only指定游标只能从第一行向最后一行滚动,并且只能通过fetch next来提取数据行。
-----[static|ketset|dynamic|fast_ward] 指定四个类型的游标
-----read only指定游标是只读的,禁止使用游标更新数据。
-----scroll_locks指定通过游标进行行定位更新或删除数据一定能够成功。
-----optimistic指定如果行在读入游标后被更新,则通过游标进行定位更新或删除将失败。
declare usersInfo_cursor cursor scroll  for select * from userInfo
-----打开游标
open usersInfo_cursor
-----提取数据行
-----@@fetch_status:返回上一个fetch语句执行后结果的一个正整数,可以使用它判断游标是否提取到了行如果返回为零,则说明游标正确提取到了数据行,非零则说明提取失败。
-----@@cursor_rows:返回当前打开的游标中符合条件的数据行数。
-----fectch语句提取数据常用用法:
-----		1. fetch first 提取游标中的第一行
-----		2. fetch next提取上次提取行之后的行
-----    3. fetch prior 提取上次提取行之前的行
-----		4. fetch last 提取游标中的最后一行
-----		5. fetch absolute n 按绝对位置提取行。n 是正整数时,则从第一行开始计数;n为负数时,则从倒数第一行开始计数;n是0,则不提取任何行。
-----		6.fetch relative n按相对位置提取上次提取行之后的第n行。n是正整数时,则提取上次所提取行之后的第n行;n是负整数时,则提取上次所提取行之前的第n行;n是0,则同一行再次被提取。
fetch next from usersInfo_cursor
while @@fetch_status = 0
begin
fetch next from usersInfo_cursor
end
--fetch absolute 3 from usersInfo_cursor
-----		关闭游标
close usersInfo_cursor
-----		释放游标
deallocate usersInfo_cursor
go
--游标变量:即数据类型为游标类型的变量。
---例句:创建游标变量
declare @var_cursor cursor
set @var_cursor = cursor scroll keyset for select * from UserInfo
open @var_cursor
fetch last from @var_cursor
close @var_cursor
deallocate @var_cursor
go

--======================================触发器和游标============================================---
go
--***函数和存储过程是T-SQL结构化程序开发的两个重要组成部分,既可以实现模块化开发,又可以提搞程序的执行性能
--**标量值函数:变量值函数的返回值是基本数据类型的单个值或单个值的表达式。

--例句:创建标量值函数
if exists(select * from sysobjects where name = 'GetUsersRole')
drop function GetUsersRole
go
create function GetUsersRole
(
@userId varchar(20),
@password varchar(20)
)
returns varchar
as
begin
declare @returnValue varchar(20)
select @returnValue = MemberName from MemberType where ID = (select MemberTypeId from UserInfo where UserId = @userId  and PassAnswer =@password )
return @returnValue
end
go
select dbo.GetUsersRole('jieyuan','791013')
--***表值函数:表值返回结果为数据表
--		表值函数分为:
--			1.多语句表值:函数要求返回类型为Table结构,与标量值函数的区别是需要在函数定义的时候,在returns关键字后面指定返回的表的结构
--			2.内联表值函数:内联表值函数是多语句表值函数的一种特殊形式,与多语句表值函数的创建方式基本相同

--例句:创建多语句表值函数  根据会员类型查询该类型下的所有用户
if exists(select * from sysobjects where name = 'GetUsersInfoByMember')
drop function GetUsersInfoByMember
go
create function GetUsersInfoByMember
(
@memberTypeId int
)
returns @table_userInfos table
(
UserId varchar(20),
UserName varchar(20)
)
as
begin
insert into @table_userInfos    --为table变量赋值使用:insert into 变量名
select UserId,UserName from UserInfo where MemberTypeId = @memberTypeId
return      --返回结果时,无需编写表达式,直接使用关键字return
end
go
select * from dbo.GetUsersInfoByMember(1)
go
--例句:创建内联表值函数   查询所有用户信息
if exists(select * from sysobjects where name = 'GetUserInfos')
drop function GetUserInfos
go
create function GetUserInfos()
returns table
as		--内联表值函数方法体中不使用beign、end包围
return
(
select UserId,UserName from UserInfo
)
go
select * from GetUserInfos()
go
--***存储过程(procedure):是SQL语句和流程控制语句的预编译集合。它可以包含逻辑控制语句和数据操作语句,也可以接受参数、输出参数、返回单个或多个结果集。
--***存储过程的优点:
--			1.允许模块化程序化设计:只要创建一次存储过程并将其保存到数据库中,以后便可无数次在程序中调用它,需要修改时可以独立于其他模块单独修改。
--			2.执行速度更快:如果某些操作需要大量的T-SQL代码需要重复执行,存储过程将比T-SQL语句批处理代码执行速度更快
--			3.减少网络流量:创建好存储过程后,一个需要数百行T-SQL代码执行的操作,由一条执行过程的单独语句就可以实现,不再需要在网络中发送数百条代码
--			4.可以作为安全机制使用:存储过程可以单独授权。如果有些操作中只有部分操作可以授予一些用户,那么可通过创建存储过程来封装这些操作,然后把存储过程的执行权限授予用户。

--***系统存储过程都是使用”sp_“开都,系统存储过程中的扩展存储过程以”xp_“开头

--例句:自定义存储过程  模拟购买卡片
if exists(select * from sysobjects where name = 'pro_saleCard')
drop proc pro_saleCard
go
create proc pro_saleCard
@cardId int,
@count int
as
declare @maxOrderId bigint
declare @newOrderId varchar(30)
declare @errorcount int = 0
declare @orderId int
select @maxOrderId = MAX(orderid) from Orders
--判断是否存在订单编号
if @maxOrderId = null
begin
set @newOrderId = CONVERT(varchar(10),GETDATE(),112)+'00001'
end
else
begin
set @newOrderId = @maxOrderId + 1
end
--开始事务
begin transaction
--添加订单信息
insert into Orders values(@newOrderId,10,GETDATE(),1)
set @errorcount += @@ERROR
select @orderId = id from Orders where OrderId = @newOrderId
--添加订单详细信息
insert into OrderDetail values(@orderId,@cardId,@count,32.00)
set @errorcount += @@ERROR
--修改卡片的状态
update Card set CardState = 0 where id = @cardId
set @errorcount += @@ERROR
--判断在执行操作时是否有错误
if(@errorcount = 0)
begin
print '执行购卡操作成功!'
commit transaction
end
else
begin
raiserror('执行购买卡片操作失败!',15,1)  	--自定义错误,错误级别15、状态1为默认值
rollback transaction
end
go
exec pro_saleCard 1032,1
go

--例句:使用系统存储过程
use master
go
exec sp_renamedb 'GameCardSale_1','GameCardSale'  --修改数据的名称
go
use GameCardSale
go
exec sp_helptext 'sp_renamedb'		--查看存储过程的定义
exec sp_tables						--查看数据库中可查看对象的列表
exec sp_help 	proc_cardPage			--查看数据库中对象(表、存储过程、视图等)的信息
exec sp_helpconstraint card		--查看表的约束
exec sp_stored_procedures			--查看当前数据库中的所有存储过程
go
use master
go
exec sp_renamedb 'GameCardSale','GameCardSale_1'
go
use GameCardSale_1
go

--例句:使用xp_cmdshell扩展存储过程执行dos命令
use master
go
--使用存储过程sp_configure启动高级选项
exec sp_configure 'show advanced options',1
go
reconfigure		--重新配置
go
exec sp_configure 'xp_cmdshell',1		--启动xp_cmdshell扩展过程
go
reconfigure		--重新配置
go
exec xp_cmdshell 'echo hello word!>>f:\aa.txt'   --使用存储过程执行dos命令
go

--****注:函数和存储过程都是数据对象。函数声明要求由返回值类型,而存储过程声明不能由返回值类型。存储过程何函数都是预编译的,所以比匿名的T-SQL代码执行效率要更高。
go

--=============================================================事物、索引、视图和同义词=============================================
go
--***事务的作用:用来保证数据的正确性和一致性。
--***事务的概念:事务是一种机制,它包含一组数据库操作命令,而且将所有的命令作为一个整体一起项数据中提交或撤销。
--***事务的特点:
--		1.原子性(Atomictiy):事务是一个完整的操作,事务的各个元素是不可分割的,要么都成功,要么都失败。
--		2.一致性(Consistency):事务完成前后,数据必须保持完全一致的状态。
--		3.隔离性(Isolation):事务是相对独立的,一个事务对数据进行修改时,其他事务是不能修改的。
--		4.持久性(Durability):事务完成后,它对于系统的影响是永久性的,即一个事务提交成功,DBMS保证它对数据库中的数据改变是永久性的,经受得住任何系统故障。
--***事务的隔离级别:
--		1.未提交读(read uncommitted):最低级别,该级别只能保证不会读取损坏的数据,即事务之间没有什么隔离,事务能改读取其他事务正在修改并提交的数据
--		2.已提交读(read committed):默认级别,该隔离级别能确保其他事务不能读取当前事务正在修改但未提交的事务。
--		3.重复读(repeatable read):隔离级别比较高,能确保其他事务不能修改当前事务中正在读取但未提交的事务。
--		4.可串行化(serializable):最高级别,事务之间完全隔离,事务之间按串行化的方式执行,所以在这种级别的隔离下不存在并行化的操作。

--例句:设置事务等级
set transaction isolation level read committed --| read committed | repleatable read | serializable |

go
--***三种事务:
--		1.显示事务:使用begin transaction 语句明确指定事务的开始。
--		2.隐式事务:通过设置set implicit transaction on语句,将隐式事务模式设置为打开。当隐式事务模式操作时,Sql server将在提交何回滚事务后自动启动新的事务。这种事务无法描述事务的开始,只提交或回滚每个事务。
--		3.自动提交事务:这是Sql Server默认的事务模式,它将每一个T-Sql语句都作为一个独立的逻辑单元来处理。
--			*在实际开发当中使用最多的是显示事务,因为自动提交事务无法将多条语句作为一个独立的逻辑来处理,隐式事务无法明确控制事务的开始位置。

---例句:使用事务完成购卡操作

declare @maxOrderId bigint
declare @newOrderId varchar(30)
declare @errorcount int = 1
declare @orderId int
select @maxOrderId = MAX(orderid) from Orders
--判断是否存在订单编号
if @maxOrderId = null
begin
set @newOrderId = CONVERT(varchar(10),GETDATE(),112)+'00001'
end
else
begin
set @newOrderId = @maxOrderId + 1
end
--开始事务
begin transaction
--添加订单信息
insert into Orders values(@newOrderId,10,GETDATE(),1)
set @errorcount += @@ERROR
select @orderId = id from Orders where OrderId = @newOrderId
--添加订单详细信息
insert into OrderDetail values(@orderId,1023,1,32.00)
set @errorcount += @@ERROR
--修改卡片的状态
update Card set CardState = 0 where id = 1023
set @errorcount += @@ERROR
--判断在执行操作时是否有错误
if(@errorcount = 0)
begin
print '执行成功'
commit transaction
end
else
begin
print '执行失败'
rollback transaction
end
go
--============================================数据库规范化设计=========================================================
--	一、数据库设计:数据库设计是指将数据库中的对象以及对象之间的关系,进行规范化和结构化的过程

--	二、数据库设计的步骤:
--		1.需求分析阶段	2.概念结构设计阶段	3.逻辑结构设计阶段	4.数据库物理设计阶段	5.数据库实施阶段	6.数据库运行和维护阶段
--	三、数据库的三范式:
--		1NF:确保每一列的原子性。如果每列都是不可再分的最小单位,即满足第一范式。
--		2NF:确保每一列都和主键之间关系,二者不是间接关系
--		3NF:即确保每一张表只描述一件事=


 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: