SQL Server高级查询与T-SQL编程笔记

一、数据库设计

1.数据流程图

1.1箭头表示数据流

1.2圆或椭圆表示加工

1.3双杠表示数据存储

1.4方框表示数据的源点或终点

2.数据字典

描述数据的信息集合,是对系统中使用的所有数据元素的定义的集合

3.E-R模型

3.1E-R图表示方法

3.1.1实体:矩形,矩形框内写明实体名称

3.1.2属性:椭圆,并用无向边将其与相应实体相连接

3.1.3联系:菱形:菱形框内写明联系名称,用无向边与相关实体相连接

3.2标识实体的原则

3.2.1实体通常是一个名词

3.2.2每一个实体仅描述一件事情或一个事物

3.2.3每个实体都是唯一的,即不能出现含义相同的实体

3.2.4联系通常是一个动词或动名词,其名称反应出实体之间的内在关联

4.联系的转换

横线(主键)

波浪线(外键)

4.1 1:1联系的转换

4.2 1:n

4.3 m:n

二、数据应用

1.DDL语句维护数据表结构

1.1创建和维护数据库

create database database-name 创建

drop database database-name 删除

1.2创建和维护数据表结构

1.2.1创建数据表

create table table-name(

        字段名1 数据类型 [列级别约束条件][默认值],

        字段名1 数据类型 [列级别约束条件][默认值],

        ......

)

create database shop(
    shopID int identity(1,1) primary key,   主键
    city varchar(50) default'武汉',         默认约束
    foreign key (customerID) references customer(customerID)    
    外键,参照客户表主键customerID
)

1.2.2新增字段

alter table 表名 add 字段名 数据类型

1.2.3删除字段

alter table 表名 drop column 字段名 

1.2.4修改字段名

alter table 表名 raname column 旧字段名 to 新字段名

1.2.5修改字段类型

alter table 表名 alter column 字段名 数据类型

2.DML语句维护数据表内容

DML——检索(查询)、更新(插入、删除、修改)

2.1新增表记录

insert [into] table-name[(字段列表)] values(值列表)

2.2更新表记录

update table-name set 字段名1=值1,字段名2=值2,.....,字段名n=值n  [where条件表达式]

2.3删除表记录

delete from table-name [where条件表达式]

3.select基本查询

3.1select基本结构语法

select from

[where <条件表达式>]

[group by column1,column2,column3.... having<条件表达式>]

[order by [asc或desc]]

说明:

a.必须的子句只有select子句和from子句

b.where子句用于对查询结果进行过滤

c.group by子句根据指定列分组,having子句对分组后的结果进行过滤

d. order by子句用于对查询结果进行排序。默认asc升序

3.2查询结果排序

select title as 标题,originalPrice as 原价,currentPrice as 团购价 
from product 
order by categoryID,currentPrice desc

3.3distinct关键字

过滤重复字段信息

select distinct customerID from orders

3.4使用top n返回指定行数

返回前几行数据

select top n column1,column2.... from table

select top 3 title 标题,currentPrice 团购价 
from product 
order by currentPrice

3.5模糊查询  like

% 匹配0到多个任意字符

-匹配任意一个

[]匹配指定一个字符集合

select title as 标题,originalPrice as 原价,currentPrice as 团购价 
from product
where title like '%KTV%'

4.聚合函数

sum 总和

max 最大值

min 最小值

avg 平均值

count 计数

select max(currentPrice) 最高团购价,min(currentPrice) 最低团购价,
avg(currentPrice) 平均团购价,count(*) 数量,sum(salesCount) 销售数量合计
from product
where categoryID=7

注:

1.count(*)用于统计当前表所选取的行数

2.count(col)用于统计当前表所选取的col列值不为null的行数

3.sum(col)用于统计当前表所选取的col列的值

count统计数据行数,sum汇总数据

5.分组查询

group by 字段列表 [having 条件表达式]

5.1基本分组查询

select categoryID 商品类型编号,count(*) 商品数量,avg(currentPrice) 平均团购价
from product
group by categoryID 
order by count(*),平均团购价 desc

5.2带条件分组查询

select categoryID 商品类型编号,count(*) 商品数量,avg(currentPrice) 平均团购价
from product
where shopID is not null
group by categoryID 
order by count(*),平均团购价 desc

5.3having子句对分组结果进行过滤 

select categoryID 商品类型编号,count(*) 商品数量,avg(currentPrice) 平均团购价
from product
where shopID is not null
group by categoryID having avg(currentPrice)>100
order by count(*),平均团购价 desc

6.连接查询

6.1内连接查询

select fieldlist(字段列) from table1 [inner] join table2 on table1.column1=table2.column2

null不与任何值匹配包括它本身

内连接是从结果表中删除与其他被连接表中没有匹配上的所有行,所以内连接可能会丢失信息 

6.2简单多表查询

select fieldlist(字段列) from table1,table2 where table1.column1=table2.column2

三、子查询

1.单行子查询

1.1子查询实质

select语句的查询结果能作为另一个语句的输入值

可用于where子句中

可用于from子句中

可以字段的形式出现在select语句的选择列中

1.2子查询应用

select title 商品标题,currentPrice 商品团购价
from product 
where areaID=(select areaID from area where areaName='江汉路')

返回结果只有一行数据

可使用单行比较符=、>、<、>=、<=、<> (不等于)进行比较

1.3子查询使用经验

1.3.1子查询通常用在位于select语句的where子句中,且可以嵌套

1.3.2编写复杂的子查询的解决思路:逐层分解查询,从最内层开始

1.3.3子查询的执行过程遵循“由里及外”的原则

1.3.4一般情况下,连接查询可改为子查询实现,但子查询不一定可以改为连接查询

1.3.5当子查询执行结果的行数较大,而主查询执行结果的行数较小时,子查询执行效率较高

2.多行子查询

返回结果是多行数据

常见的多行比较符in、all、any、some

2.1in比较符

例:查询营业地点江汉路、武广、亚贸地区的商品信息时,要求输出商品标题、商品团购价和区域编号

select title 标题,currentPrice 商品团购价
from product
where areaID in(select areaID 
                from area 
                where areaName='江汉路' or areaName='武广' or areaName='亚贸')

2.2all关键字子查询

表达式或字段 多行比较运算符 all(子查询)

all运算符的含义:比所有小

                             >all 表示大于最小值 比所有大

例:查询团购价比所有食品类商品团购价都高的商品信息,要求输出商品标题和商品团购价

select title 商品标题,currentPrice 团购价
from product
where currentPrice >all(select currentPrice 
                        from product 
                        where categoryID=(select categoryID 
                                            from category 
                                            where categoryName='食品'))

2.3any/some关键字子查询

表达式或字段 多行比较运算符 any/some(子查询)

any/some运算符的含义:小于最大值

                                        =any/some 与in运算符等价 比所有大

                                         >any/some 大于最小值

例:查询团购价比任意一款食品类商品团购价高的商品时,输出商品标题和商品团购价

select title 商品标题,currentPrice 团购价
from product
where currentPrice >any(select currentPrice 
                        from product 
                        where categoryID=(select categoryID 
                                            from category 
                                            where categoryName='食品'))

3.子查询非典型应用

3.1在from子句中使用子查询

使用group by 只能显示聚合函数和分组的字段

select A.categoryID 商品类型编号,A.title 商品标题,
A.currentPrice 商品团购价,B.avgPrice 该类商品平均团购价
from product A,
(select categoryID,avg(currentPrice) avgPrice 
 from product 
 group by categoryID) B
where A.categoryID=B.categoryID

3.2在select子句中使用子查询

实质:将子查询的执行结果作为select子句的列

select count(productID) 商品个数,
(select count(distinct productID) 
from orderDetail) 已订购商品个数 
from product

3.3exists关键字

主查询表达式 [not] exists (子查询)

exists指定一个子查询,用于检测行的存在

例:查询所有订购过商品的客户姓名

select customerName 客户姓名 
from customer c
where exists (select *
              from orders 
              where customerID=c.customerID)

4.在DML语句中使用子查询

4.1在update子句中使用子查询

例:将所有火锅类餐饮的团购价降低10%

Update product 
set currentPrice=currentPrice * 0.9
where categoryID in(select categoryID 
                    from category 
                    where categoryName='火锅')

4.2在delete子句中使用子查询

例:删除客户刘亚蒙所有订购信息

delete from orders 
where ordersID in(select orderID 
                  from orders 
                  where customerID=(select customerID 
                                    from customer
                                    where customerName='刘亚蒙'))

四、T-SQL编程

1.T-SQL常量

1.1数字常量

整数常量、小数常量(前面可加正负号)

浮点常量 符号e指定 1.5e3

1.2字符串常量

包含在单引号

包含字母、数字以及特殊符号!@#

例'Football'

1.3日期和时间常量

例:'2017-01-13','03/03/2016'

1.4符号常量

CURRENT-DATE 当前日期

CURRENT-TIME 当前时间

CURRENT-TIMESTAMP 当前时间戳

2.T-SQL标识符

2.1常规标识符

以ASCII字母、Unicode字母、下划线、@或#开头,其后可跟一个或若干个ASCII字母、Unicode字母、下划线、美元符号、@、#,但不能全为下划线、@、#,不能是T-SQL保留字,不允许嵌入空格或其他特殊字符

2.2分隔标识符

包括在双引号或方括号内的常规标识符

3.T-SQL局部变量定义

名称必须以@开始,用于保存单个数据值

局部变量使用declare语句声明,所有局部变量在声明后均初始化为null

declare{

        @varaible-name(变量名)  datatype(数据类型)[,....n]

}

declare @lastname varchar(30),@firstname varchar(20)

4.使用set语句为局部变量赋值

set @varaible-name=expression

一个set语句仅能为一个变量赋值

use lingju
go
declare @count int,@categoryID int
set @categoryID=7
set @count=(select count(*) from product where categoryID=@categoryID)

print '火锅类商品数量:'+convert(varchar(50),@count)

5.使用select语句为局部变量赋值

select @varaible-name=expression

 一个select语句仅能为一个变量赋值

use lingju
go
declare @categoryName1 nvarchar(20),@categoryName2 nvarchar(20)
select @categoryName1='火锅'
select @categoryName2=(select categoryName from category where categoryID23)

select @categoryName1,@categoryName2

6.T-SQL全局变量

SQL Server系统内部事先定义好的变量

                                 SQL Server 2014常见的全局变量
变量名 作用
@@ERROR 返回执行上一条Transact-SQL语句能返回的错误号
@@IDENTITY 返回最后插入的标志值
@@MAX-CONNECTIONS 返回SQL Server实例所允许同时连接的最大用户数
@@ROWCOUNT 返回上一条语句影响的行数
@@SERVERNAME 返回运行SQL Server的本地服务器名称
@@SERVICENAME 返回SQL Serve正在运行的注册表项的名称
@@TRANCOUNT 返回当前连接的活动事物数

7.流程控制语句

7.1begin..end语句

相当于一对花括号{}

至少包含一条SQL语句,否则将出错

主要用于if..else语句、while循环和case语句的执行体

7.2if..else条件判断语句

if logical-expression

        expression1

[else

        expression2]

use lingju
go
declare @years int,@name varchar(20)
set @name='刘亚蒙'
set @years=(select datediff(YYYY,birthday,getdate())
            from customer 
            where customerName=@name)
print '客户'+@name+'的年龄是'+convert(nvarchar(10),
@years)+'岁'
if @years<=10
    print '未成年'
else
    print '已成年'

datediff(datepart,startdate,enddate) 返回enddate和startdate之间的间隔

datepart世间间隔YYYY表示年

7.3while循环语句

while logical-expression

begin

        expression

        [break]

        [continue]

end

例:计算1+2+3+...+10的值

declare @x int=1
declare @total int=0
while @x<=10
begin
    set @total +=@x
    set @x +=1
end

7.4case选择语句

7.4.1简单表达式

case input-expression

        when when-expression then result-expression

        [...n]

        [else else-result-expression]

end

use lingju
go
select categoryName 商品小类名称,商品大类名称=
    case p-categoryID
        when 1 then '美食'
        when 2 then '酒店'
        else categoryName
    end
from category

7.4.2选择表达式

case 

        when boolean-expression then result-expression

        [...n]

        [else else-result-expression]

end

use lingju
go
select title 商品标题,优惠程度=
case 
    when currentPrice/originalPrice<=0.4 then '巨优惠'
    when currentPrice/originalPrice>0.4 and 
        currentPrice/originalPrice<=0.6 then '很优惠'
    when currentPrice/originalPrice>0.6 and 
        currentPrice/originalPrice<=0.8 then '一般优惠'
    else '普通优惠'
end
from product

8.系统存储过程

一组预编译的T-SQL语句

所有系统存储过程均已sp-开始

                                              常用系统存储过程
系统存储过程名称 说明
sp-databases 列出服务器上所有的数据库
sp-helpdb 报告有关指定数据库或所有数据库的信息
sp-renamedb 更改数据库名称,sp-renamedb 'MyDB1' 'My2'将MyDB1改为My2
sp-tables 返回当前环境下可查询的对象列表
sp-columns 查看某个表的所有列信息,sp-columns customer
sp-help 查看某个表的所有信息
sp-helpconstraint 查看某个表的约束
sp-helpindex 查看某个表的索引
sp-stored-procedures 列出当前环境中所有的存储过程
sp-password 修改登录账号密码,sp-password null,'another' 'abc'用于将登录名abc的密码修改为another

使用execute | exec存储过程名 '......'  命令执行存储过程 

例:exec sp-databases 或者 execute sp-databases

9.用户自定义存储过程

create proc[edure]存储过程关键字 proc-name存储过程名称

[{@parameter-name data-type}=[默认值]] [output]输出类型,...,n]

as

procedure-body存储过程主体

use lingju
go
if exists (select * from sysobject where name='proc-Info')
    drop procedure proc-Info
go
create procedure proc-Info
as
select title,categoryName,currentPrice,areaName,shopName
from product p,category c,area a,shop s
where p.categoryID=c.categoryID and p.areaID=a.areaID and p.shopID=s.shopID
order by categoryName,currentPrice

 exec proc-Info

10.带输入参数存储过程

参数类型默认为输入类型

例:获取指定类型的商品个数和平均团购价

use lingju
go
if exists(select * from sysobject where name='proc-PSGC')
    drop procedure proc-PSGC
go
create procedure proc-PSGC(
    @categoryName nvarchar(20)
)
as
select categoryName 商品类型名,count(p.productID) 商品数量,
avg(currentPrice) 平均团购价 
from product p,category c
where p.categoryID and categoryName=@categoryName
group by categoryName 
order by 平均团购价

exec proc-PSGC '火锅'

注:执行带参数的存储过程时,传入值的类型、个数、顺序都需要与存储过程中定义的参数逐一对应 

11.带输出参数存储过程

输出参数必须在创建存储的过程时,使用output关键字进行声明

有返回值的方法要声明变量来接收

例:获取指定商品类型的最高团购价,要求输出指定商品类型的最高团购价及其商品名

use lingju
go
if exists (select * from sysobjects where name='proc-MaxPrice')
    drop procedure proc-MaxPrice
go
create procedure proc-MaxPrice(
    @categoryName nvarchar(20),
    @maxPrice money output,
    @productName nvarchar(20) output
)
as
select @maxPrice=max(currentPrice) 
from product p,category c 
where p.categoryID=c.categoryID
and categoryName=@categoryName
select @productName=title 
from product 
where currentPrice=@maxPrice
go
declare @categoryName nvarchar(20)
declare @maxPrice money
declare @productName nvarchar(20)
set @categoryName='火锅'

exec proc-MaxPrice @categoryName,@maxPrice output,
@categoryName output '价格是:'+convert(nvarchar(20),
@maxPrice)+'元'

五、常见数据库对象

1.视图 (数据库)

1.1视图的概念和特点

1.1.1是一种数据库对象,是一个从一张表、多张表或视图中导出的虚表,视图的结构和数据是对数据表进行查询的结果

1.1.2视图仅存放视图的定义,不存放视图所对应的数据

1.1.3如果基表中的数据发生变化,则从视图中查询出的数据也随之改变

1.2视图的优点

1.2.1关注点聚焦

1.2.2简化操作

1.2.3定制数据

1.2.4在合并分割数据时保持表原有结构关系

1.2.5细粒化安全机制——用户仅能查看和修改他们能看到的数据

1.3使用企业管理器创建视图

资源管理器——数据库——视图——右键

1.4使用T-SQL创建视图

create view [schema-name]视图所属架构名 view-name视图名

        [(column[1.....n])]视图中所使用的列名

as select-statement视图的主体、select子句

查看

select * from 视图名

例:创建一个用于生成每个订单金额的视图,并利用该视图更新表中相应订单的金额

create view v-orderAmount as
select od.ordersID,sum(p.currentPrice * od.quantity) calamount 
from orders o,ordersdetail od,product p
where o.ordersID=od.ordersID and p.productID=od.productID
group by ordersID
update orders set amount=(select calamount 
                          from v-ordersAmount 
                          where ordersID=orders.ordersID)

2.索引(表)

加快数据处理速度的最普遍的优化方法

2.1索引使用场合

2.1.1经常需要搜索的列

2.1.2主键

2.1.3外键

2.1.4排序

2.1.5分组

2.1.6where子句

2.2索引分类

2.2.1聚集索引

以该字段作为排序依据,一个表仅能建立一个聚集索引

插入慢、查询快、所需空间小

2.2.2非聚集索引

2.2.3唯一索引

默认为聚集索引

2.3使用企业管理器创建索引

选中表——索引——右键——新建索引——输入索引名——添加

2.4T-SQL创建索引

2.4.1创建索引

create [unique] [clustered | nonclustered]

index index-name

on table-name(column-name)

 unique唯一索引

clustered聚集索引

nonclustered非聚集索引,默认索引

index-name索引名

create index idx-price on product(currentPrice)

2.4.2删除

 drop index index-name on table-name

alter table-name drop index index-name

例:  drop index idx-price on product

         alter table product drop index idx-price

2.4.3创建组合索引(多个)

例:create index idx-price-title on product(price,title)

3.数据库事务

一个由用户所定义的完整的工作单元。要么全部执行,要么全部不执行

3.1事务特性

3.1.1原子性

一变全变,不变全不变

3.1.2一致性

完成时,所有数据保持一致

3.1.3隔离性

事务状态,要么修改前要么修改后

3.1.4持久性

影响是永久的

3.2事务的分类

3.2.1显示事务

需要由用户显示定义事务开始或结束

begin transaction 启动事务

commit transaction 提交事务

rollback transaction 回滚事务  遇到错误

3.2.2隐式事务

不需要begin transaction

执行set implicit-transactions on语句可进入隐式事务模式

3.2.3自动提交事务

是SQL Server默认的事务模式,将每个T-SQL语句都视为一个事务

例:生成两条记录订单表和订单明细表

use lingju
go
if exists(select * from sysobjects where name='proc-insert')
    drop procedure proc-insert
go
create procedure proc-insert(
    @ordersDate varchar(20),——下单日期
    @customerName varchar(20),——客户姓名
    @title1 varchar(50),——第一件商品名
    @quantity1 int,——第一件商品数量
    @title2 varchar(50),——第二件商品名
    @quantity2 int ——第二件商品数量
)
as
declare @customerID int;——客户编号
declare @productID1 int;——第一件商品编号
declare @productID2 int;——第二件商品编号
declare @ordersID int;——订单编号
select @customerID=customerID 
from customer 
where customerName=@customerName
begin transaction ——启动事务
——添加订单表记录
insert into orders(customerID,ordersDate) 
values(@customerID.convert(date,@ordersDate))
if @@error=0 ——添加订单表记录成功
begin
    select @ordersID=max(ordersID) from orders ——获取新增订单编号
    select @productID1=productID from product where title=@title1 ——第一件商品编号
——添加第一件商品到订单明细表
insert into ordersDatail(ordersID,productID,quantity)
values(@ordersID,@productID1,@quantity1)
select @productID2=productID from product where title=@title2 ——第二件商品编号
——添加第二件商品到订单明细表
......
if @@error=0 ——添加订单表和订单明细表记录成功
begin
    print '添加订单明细成功'
    commit transaction ——提交事务
end
else
begin
    print '添加订单明细失败'
    rollback transaction ——回滚事务
end
end
else
begin
    print '添加订单失败'
    rollback transaction ——提交事务
end

declare @ordersDate varchar(20)='2019-3-8'
declare @customerName varchar(20)='雷亚波'
declare @title1 varchar(50)='菠萝爆肉片'
declare @quantity1 int=2
declare @title2 varchar(50)='糖醋排骨'
declare @quantity2 int=5

exec proc-insert   
@ordersDate,@customerName,@title1,@quantity1,@title2,@quantity2

4.触发器

保证数据完整性的一种方法,由事务触发,执行insert、delete和update时会激活它执行,用于加强数据的完整性约束和业务规则

可实现检查约束、维护冗余数据,编护外键列数据

4.1创建触发器语法

create trigger trigger-name on table-name

for/after/instead of delete/insert/update

as

sql-statement

4.2inserted表和deleted表

由系统维护,存在内存中

作用:a:inserted表存放在由于执行insert或update语句而要向表中插入的所有行

           b:deleted表存放在由于执行delete或update语句而要向表中删除的所有行

4.3instead of触发器和after触发器

每一个表上只能创建一个instead of触发器,但可创建多个after

instead of:用来代替通常的触发动作,当对表进行insert、update或delete操作时,系统不是直接对表执行这些操作,而是把操作内容交给触发器,让触发器检查是否正确,正确执行操作

不仅可在表上定义,还可在带有一个或多个基表的视图上定义

after:定义对表执行insert、update或delete语句操作之后再执行的操作

        只能在表上指定,且动作晚于约束处理

4.4instead of实现数据新增

例:新增商品数据时,确保新增产品的团购价低于原价

use lingju
go
if exists(select * from sysobjects where name='trig-insert')
    drop trigger trig-insert
go
create trigger trig-insert on product instead of insert
as
declare @title nvarchar(50)
declare @originalPrice decimal(10,2),@currentPrice decimal(10,2)
select @title=title,@originalPrice=originalPrice,@currentPrice=currentPrice
from inserted
if @currentPrice>=@originalPrice
begin
    print '团购价不能大于等于原价'
end
else
begin
    print '成功新增商品记录'
    ————执行新增操作
    insert into product (title,originalPrice,currentPrice)
    values (@title,@originalPrice,@currentPrice)
end

insert into product (title,originalPrice,currentPrice)
    values ('凯威啤酒屋',78,88)

4.5 after实现数据新增

例:新增商品数据时,确保新增产品的团购价低于原价

use lingju
go
if exists(select * from sysobjects where name='trig-insert')
    drop trigger trig-insert
go
create trigger trig-insert on product after insert
as
declare @title nvarchar(50)
declare @originalPrice decimal(10,2),@currentPrice decimal(10,2)
select @title=title,@originalPrice=originalPrice,@currentPrice=currentPrice
from inserted
if @currentPrice>=@originalPrice
begin
    print '团购价不能大于等于原价'
    rollback transaction
end
else
begin
    print '成功新增商品记录'
end

insert into product (title,originalPrice,currentPrice)
    values ('凯威啤酒屋',78,88)

六、数据库安全管理

1.SQL Server安全机制和登录账户管理

1.1SQL Server安全机制

1.1.1登录账户(Login)

用来控制对任何SQL Server系统的访问权限,验证成功连接

1.1.2数据库用户(User)

在特定的数据库内创建,并关联一个登录账户

1.1.3账户(Accout)

由用户管理器所创建

1.2创建登录账户

1.2.1ssms

对象资源管理器——安全性——登录名——右键——新建登录名

1.2.2T-SQL

1.2.2.1windows登录账户

create login login-name from windows

 login-name:必须用[]括起,格式:域名/计算机名/用户名或组名

1.2.2.2SQL Server登录账户

create login login-name with password='password',default-database=db-name

if suser-ID('emp') is not null
    drop login emp
go
create login emp with password='123',default-database=lingju
go

1.3维护登录账户

1.3.1修改登录名

alter login emp1 with name=emp2

1.3.2修改密码

alter login emp2 with password='123456'

1.3.3禁用登录名

alter login emp2 disable

1.3.4启用登录名

alter login emp2 enable

1.3.5删除登录名

drop login emp2

2.数据库用户管理

2.1创建数据库用户

2.1.1ssms

对象资源管理器——数据库——安全性——用户——右键——新建用户(带登录名的SQL用户)

2.1.2T-SQL

create user user-name from login login-name [with default-schema=schema-name]

例:创建与emp登录名相对应的数据库用户 user-emp,默认架构为schema-emp

use lingju
go
if user-id ('user-emp') is not null
    drop user user-emp
go
create user user-emp from login emp with default-schema=schema-emp
go

2.2两个特殊的数据库用户

2.2.1 dbo

默认用户,系统自动生成的,拥有在数据库中操作的所有权限

2.2.2guest

默认用户,系统自动生成的,授予guest用户的权限由数据库中设有用户账户的用户继承

2.3架构管理

不能删除的架构:dbo、guest、sys、information-schema也不能创建

2.3.1ssms

对象资源管理器——数据库——安全性——架构

2.3.2T-SQL命令创建架构

例:定义名称为schema-emp的架构,指定该架构的所有为user-emp,并创建该架构所拥有的数据库对象,此处为表employee

use lingju
go
if schema-id('schema-emp') is not null
    drop schema schema-emp
go
create schema schema-emp authorization user-emp
    create table employee(empID int primary key,
                          empName varchar(20)
    )
go

2.3.3修改和删除架构

修改架构是指将架构中的对象转移到其他架构中

例:将dbo架构拥有的area表转移到schema-emp架构中

use lingju
go
if schema-id('schema-emp') is not null
    alter schema schema-emp transfer dbo-area
go

 例:将架构schema-emp的所有者更改为数据库用户dbo

alter authorization on schema::schema-emp to dbo

只有架构中不再包含有对象时,才可以被删除drop schema 

2.3.4维护数据库用户

例:将lingju数据库中的user-emp数据库用户更名为user-emp1

use lingju
go
if user-id('user-emp') is not null
    alter user user-emp with name=user-emp1

例:将lingju数据库中的user-emp数据库用户的默认架构更改为dbo

use lingju
go
if user-id('user-emp') is not null
    alter user user-emp with default-schema=dbo

例:将lingju数据库中的user-emp数据库用户对应的登录名修改为mgr

use lingju
go
if user-id('user-emp') is not null
    alter user myemp with login=mgr

3.数据库角色管理

3.1SQL Server角色概要

3.1.1服务器级:固定服务器角色

3.1.2数据库级:固定数据库角色、用户定义数据库角色、应用程序角色

3.2固定服务器角色

3.2.1执行sp-addsrvrolemember存储过程向固定服务器角色中添加成员

例:将数据库登录emp添加到固定服务器角色sysadmin中

execute sp-addsrvrolemember emp,sysadmin

3.2.2执行sp-dropsrvrolemember存储过程向删除固定服务器角色成员

例:将数据库登录emp添加到固定服务器角色sysadmin中

execute sp-dropsrvrolemember emp,sysadmin

3.2.3执行is-srvrolemember函数判断指定的登录名是否为某个固定服务器角色

例:当前登录名是否为sysadmin固定服务器角色的成员

if is-srvrolemember('sysadmin')=1
    print 'current user' 's login is a member of the sysadmin role'
else if is-srvrolemember('sysadmin')=0
    print 'current user' 's login is not a member of the sysadmin role'
else if is-srvrolemember('sysadmin') is null
    print 'error:invalid server role specified'

3.2.4执行sp-helpsrvrolemember存储过程查看固定服务器角色的成员

例:查看固定服务器角色sysadmin的成员

execute sp-helpsrvrolemember sysadmin

3.3固定数据库角色

3.3.1执行sp-addrolemember存储过程向固定数据库角色中添加成员

例:将数据库用户user-emp添加到固定数据库角色db-ddladmin中

use lingju
execute sp-addrolemember db-ddladmin,user-emp

3.3.2执行sp-droprolemember存储过程向删除固定数据库角色成员

例:从固定数据库角色db-ddladmin中删除数据库用户user-emp

use lingju
execute sp-droprolemember db-ddladmin,user-emp

3.3.3使用sp-helprolemember存储过程查看固定数据库角色的成员

例:查看固定数据库角色db-ddladmin的成员

execute sp-helprolemember db-ddladmin

3.4用户自定义数据库角色

3.4.1ssms创建

对象资源管理器——数据库——安全性——角色——数据库角色——新建

3.4.2T-SQL命令创建用户自定义数据库角色

例:创建名为role-emp的数据库角色,其所有者是user-emp

use lingju
go
if exists(select * from sys.database-principals where name='role-emp' and type='r')
    drop role role-emp
go
create role role-emp authorization user-emp
go

3.4.3为角色添加和删除成员

例:将user-emp数据库用户添加到角色role-emp中

execute sp-addrolemember role-emp,user-emp

 例:将user-emp数据库用户从角色role-emp中删除

execute sp-droprolemember role-emp,user-emp

可以使用 sys.database-principals安全目录查看当前数据库中所有数据库角色信息

使用 sys.database-role-member安全目录视图查看当前数据库中所有数据库角色ID和其成员ID信息

3.4.4修改和删除用户自定义数据库角色

例:将用户自定义数据库角色buyers改名为purchasing

alter role buyers with name=purchasing

例:删除成员jack

alter role sales drop member jack

3.5应用程序角色

是一个数据库主体,它使用应用程序能够用其自身的、类似用户的权限来运行

create application role application-role-name

with password='password'

default-schema=schema-name

例:在lingju数据库中创建一个名为approle的应用程序角色,密码为app123,默认架构为schema-emp

use lingju
go
create application role approle
        with password='app123'
        default-schema=schema-emp
go

在默认状态下,新建的应用程序角色是非活动的,只有激活后才能发挥作用

例:激活数据库lingju中的应用程序角色approle

use lingju
go
sp-setapprole approle,'app123'
go

4.数据库权限管理

4.1ssms实现用户授权

对象资源管理器——数据库——安全性——用户——右键——属性——安全对象——搜索——添加特定类型的所有对象——确定——对象类型表

4.2使用grant语句实现用户授权

例:授予数据库用户user-emp查询、新增表employee的权限

use lingju
grant select,update on schema-emp.employee to user-emp

例:授予数据库用户user-emp关于表employee的delete权限,并允许该用户将这个权限转授给其他用户

use lingju
grant delete on schema-emp,employee to user-emp with grant option

 例:授予数据库用户user-emp操作表中指定列的权限(具有更新product表中title列和areaID列权限)

use lingju
grant update on schema-mgr.product(title,areaID)
to user-mgr

例:授予数据库用户user-emp具有操作数据库lingju的所有权限

use lingju
grant all on database::lingju to user-mgr

4.3使用revoke语句实现权限收回

例:将数据库用户user-emp对表employee的delete权限进行收回

revoke delete on schema-emp.employee from user-emp

 例:收回数据库用户user-emp更新product表中title列和areaID列的权限,并允许该用户将这个权限转授给其他用户

revoke update on schema-mgr.product(title,areaID) from user-mgr cascade

例:将数据库用户user-cus创建表的权限收回

revoke create table from user-cus

4.4否认权限(拒绝权限)deny

4.4.1安全主体获得权限的方式:

grant语句为其授予权限

作为角色成员继承角色的权限

4.4.2例:删除数据库用户user-mgr更新product表中title列和areaID列的权限,而且禁止该用户通过作为其他角色成员获得针对这两列的update权限

deny update on schema-mgr.product(title,areaID) to user-mgr

4.4.3例:将数据库用户user-mgr对product表中title列和areaID列的处于否认状态的update权限状态恢复到自然状态

revoke update on schema-mgr.product(title,areaID) to user-mgr

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