【数据库原理与应用 - 第六章】T-SQL 在SQL Server的使用

news2024/7/4 5:56:15

目录

一、数据库定义语言DDL

1、数据库的定义

(1)创建数据库

(2)管理数据库

2、基本表的定义

(1)创建基本表

(2)修改基本表

3、索引的定义

(1)创建索引

(2)管理索引

4、视图的定义

(1)创建视图

(2)修改删除视图

(3)视图的查询和更新

二、数据查询语言DQL

1、select语句介绍

2、简单查询 

(1)查询表中的若干行

(2)对查询结果进行排序

(3)汇总查询

3、连接查询

(1)内连接 inner join

(2)外连接 outer join

(3)自连接 self join 

(4)交叉连接 cross join

4、嵌套查询

(1)非相关子查询

(2)相关子查询

5、组合查询

(1)union并操作

(2)intersect交操作

(3)except差操作

三、数据更新语言DML

1、插入数据

(1)插入单个元组

(2)插入多个元组

2、修改数据

(1)修改数据语法格式

(2)修改单个元组

(3)修改多个元组

3、删除数据

(1)delete

(2)truncate

4、数据更新操作检查完整性

(1)插入数据时需要分别检查实体完整性与参照完整性

(2)删除数据时需要检查参照完整性

(3)修改数据时需要检查实体完整性与参照完整性

四、数据控制语言DML

1、数据控制方法

2、sql server数据库操作权限

3、对象权限设置

4、语句权限设置

五、数据库初步编程

1、变量

(1)变量的声明

(2)变量的赋值

2、流程控制

(1)begin end

(2)if else

(3)while

(4)case

(5)waitfor

(6)goto

(7)注释

3、存储过程编程

(1)创建存储过程

(2)执行存储过程

(3)存储过程应用实例

(4)删除和修改存储过程

4、触发器编程

(1)DML触发器

(2)DDL触发器

(3)删除和修改触发器

六、嵌入式SQL


一、数据库定义语言DDL

1、数据库的定义

(1)创建数据库

create database 数据库名称

[ on --定义数据库的数据文件
    [primary]  --设置主文件组
    <数据文件描述符>[,...n]  --设置数据文件的属性
    [,filegroup 文件组名 <数据文件描述符>[,...n]] --设置次文件组及数据文件属性
]

[ log on                      --定义数据库的日志文件
    {<日志文件描述符>}[,...n]  --设置日志文件的属性
]

其中<数据文件描述符>和<日志文件描述符>为以下属性组合:

( name=逻辑文件名, --设置在SQL Server引用的名称
  filename='物理文件名'  --设置文件中磁盘存放的路径和名称
  [,size=文件初始容量]
  [,maxsize=文件最大容量|unlimited]
  [,filegrowth=文件增长率%]  --设置文件自动增量
)

例:在E盘的data文件夹下建立名为高校图书管理的数据库,主数据文件为高校图书管理_data,初始容量10MB,最大容量为50MB,增幅为10MB。日志文件为高校图管理_log,初始容量大小5MB,最大容量为20MB,增幅为5MB。

create database 高校图书管理

on primary  --设置主文件组
(
    name=高校图书管理_data
    filename='E:\data\高校图书管理_data.mdf',
    size=10MB
    maxsize=50MB
    filegrowth=10%
) --设置数据文件的属性

log on                      --定义数据库的日志文件
(
    name=高校图书管理_log,
    size=5MB,
    maxsize=20MB,
    filegrowth=5%
) --设置日志文件的属性

go

注:如果创建时没有指定日志文件,系统自动创建一个初始容量为0.75MB的日志文件,且无最大容量限制

(2)管理数据库

alter database 数据库名称 --修改数据库

drop database 数据库名称 --删除数据库

sp_helpdb 数据库名称 --查看数据库属性

2、基本表的定义

(1)创建基本表

create table 表名
(
    列名,数据类型[(长度)]
    [default 常量表达式] --定义默认值
    | [ indetity[(初值,增量)] ] --定义标识列
    
    [constraint 约束名]
    {
        [NULL|NOT NULL] --设置空或非空约束

        |[default]  --设置默认值约束

        |[ [primary key|unique]  --设置主键或唯一性约束 
           [clustered|nonclustered] --设置聚集或非聚集索引
         ]  
        
        |[foreign key(外键列)] references 被参照表名(外键列)  --设置外键约束

        |check(逻辑表达式)  --设置检查约束
    }
)

主键约束格式

[constraint<约束名>]primary key(<列名>...) 

eg:
constraint c3 primary key(dzkh,tsbh)  --设置主键单独列出

dzkh nvarchar(20) primary key  --直接在列后设置主键

外键约束格式

[constraint<约束名>]foreign key(<列名>) references<主键表名>(<列名>)

eg:
constraint c1 foreign key(类别编号) references 读者类别(类别编号) --单独列出
  • 外键设在哪个表?  哪个表的某属性需要被约束,则该表的该属性设为外键
  • eg:选修表中学号需要被约束,则外键表为选修表,主键表为学生表

唯一性约束格式

constraint 约束名 unique(<列名>)
主键与唯一性约束区别
主键唯一性约束
唯一地标识表中的某一条记录,可以定义一列或多列为主键限制不受主键约束的列上的数据的唯一性,用于作为访问某行的可选手段,一个表上可以放置多个唯一性约束
没有重复值,不允许空没有重复值,允许空
可作外键不可作外键

【例1】创建读者表

create table 读者
(
    读者卡号 nvarchar(10) primary key,
    姓名 nvarchar(16) NOT NULL,
    性别 nvarchar(1) NOT NULL default'男',
    单位 nvarchar(30) NOT NULL,
    办卡日期 date NOT NULL,
    卡状态 nvarchar(5) NOT NULL,
    类别编号 nvarchar(2),
    constraint c1 check(性别 in('男','女')),
    constraint c2 foreign key(类别编号) references 读者类别(类别编号)
)
go

【例2】创建借阅表 

create table 读者
(
    读者卡号 nvarchar(10),
    图书编号 nvarchar(8),
    借书日期 date NOT NULL,
    还书日期 date,
    constraint c3 primary key(读者卡号,图书编号),
    constraint c4 foreign key(读者卡号) references 读者(读者卡号),
    constraint c5 foreign key(图书编号) references 图书(图书编号)
)
go

(2)修改基本表

【例1】在读者表新增整型列id,该列作为每行数据的标识,并自动增加,初始值为1;在读者姓名一列增加唯一性约束,约束名为uk_dz_dzxm

use 高校图书管理
go

alter table 读者
add id int indetity(1,1)
go

alter table 读者
whith nocheck --禁用约束检查
add constraint uk_dz_dzxm unique(姓名)
go

注:

  1. identity是“自增标识列”,每个表只能创建一个标识列,数据类型只能是数值型,不能对标识列绑定默认值或default约束
  2. 如果想忽略对原有数据的约束检查,使用with nocheck——使增加的约束只对以后更新或插入的数据起作用,不能将with check/with nocheck用于主键和唯一性约束
  3. 新增列不能定义为NOT NULL

【例2】将读者类别表中类别编号设为主键

alter table 读者
add primary key(类别编号)

【例3】将读者表的id列和姓名列删除

alter table 读者
drop column id
go


alter table 读者
drop constraint uk_dz_dzxm
go

alter table 读者
drop column 姓名
go

注意:如果某列有约束或默认值,该列无法删除。必须先删约束,再删该列

3、索引的定义

索引机制:执行查询操作时,先查询索引文件得出元组在数据表的地址,再根据这个地址在数据表中直接取出该元组(跟map类似)

聚集索引与非聚集索引的区别

  • 聚集索引一个表只能有一个,非聚集索引一个表可以存在多个
  • 聚集索引存储记录是物理上连续存在,非聚集索引是逻辑上的连续,物理存储并不连续
  • 聚集索引:物理存储按照索引排序,索引的键值逻辑顺序决定了表数据行的物理存储顺序。
  • 非聚集索引:物理存储不按照索引排序,仅仅只是对数据列创建相应的索引,不影响整个表的物理存储顺序
  • 聚集索引插入数据时速度要慢,查询数据比非聚集数据的速度快。

(1)创建索引

create [unique][clustered][nonclustered] index 索引名
on {表名|视图名}(列名1[ASC|DESC]……)
  • unique 唯一性索引:不允许具有索引值相同的行,省略unique时,创建的是非唯一索引
  • clustered 聚集性索引:省略clustered时,创建的是非聚集性索引

【例1】在图书表的书名列上,创建一个名称为idx_sm的唯一索引,并依据书名升序排序

use 高校图书管理
go
create unique index idx_sm on 图书(书名)
go

【例2】在读者表的姓名和性别列上,创建一个名称为idx_xmxb的唯一非聚集性复合索引,依据姓名升序、性别降序排序

create unique nonclustered index idx_xmxb on 读者(姓名,性别DESC)

(2)管理索引

① 修改索引

alter index 索引名 on 表名|视图名
{rebuild|reorganize|disable}
  • rebuild:指定将相同的列、索引类型、唯一性属性、排列顺序重新生成索引,可以重新启动已禁用的索引
  • reorganize:重新组织索引
  • disable:将索引标志为禁用

② 删除索引

drop index 索引名
  • 如果要删除为了实现主键或唯一约束而创建的索引,必须删除约束
  • 在删除聚集索引时,表中所有非聚集性索引都被删除

③ 查看索引

exec sp_helpindex '表名'

【例1】查看读者表定义的索引信息

exec sp_helpindex '读者'

4、视图的定义

(1)创建视图

create view <视图名>(列名……)
as<select 语句>
[with check option]
  • select语句中不允许含有compute (by)子句、into子句、distinct子句
  • with check option:强制视图中执行所有的数据插入、删除和更新操作必须满足select的where表达式

① 行列子集视图

行列子集视图是指只删除基本表的某些行和某些列,但保留了码的视图

【例1】创建一个名为view_dw的视图,通过该视图,可以查询读者单位为"数计学院"的所有读者信息。该视图可以查询读者单位为"数计学院"的所有读者信息,要求透过该视图进行的更新操作只涉及数计学院的读者

create view view_dw
as select *
   from 读者
   where 单位='数计学院'
   with check option
select *
from view_dw

② 连接视图

连接视图指多个数据表连接起来的视图

【例2】创建一个名为view_dzjy的视图,通过该视图可以查询每一个读者的姓名、性别、单位、图书编号、书名、借书日期、还书日期

create view view_dzjy
as select xm,xb,dw,图书.tsbh,sm,jsrq,hsrq
from 读者,图书,借阅
where 图书.tsbh=借阅.tsbh and 读者.dzkh=借阅.dzkh

③ 分组统计视图

通过使用聚集函数生成指定字段所需的统计数据

【例3】在高校图书管理数据库中,创建一个名为 view_dzjytj 的视图,要求通过该视图,可以查询每一位读者的借书册数

create view view_dzjytj(读者卡号,借书册数)
as select 读者卡号,count(*)
   from 借阅
   group by 读者卡号 --根据读者卡号分组
create view view_dzjytj
as select 读者卡号,count(*) as 借书册数
   from 借阅
   group by 读者卡号 --根据读者卡号分组

【例4】创建一个名为view_dzjyxx的视图,要求通过该视图,可以查询每一位读者的详细信息和借书册数

可以将例3中的视图和读者表连接

create view view_dzjyxx
as select 读者.*,借阅册数
   from view_dzjytj,读者
   where 读者.读者卡号=view_dzjytj.读者卡号

(2)修改删除视图

① 修改视图

alter view 视图名(列名……)
as<select 语句>
[with check option]

alter view 无法更改视图名称

② 删除视图

drop view 视图名

一个视图被删除后,由该视图导出的其他视图也将失效

(3)视图的查询和更新

① 视图更新的限制

  • 视图的字段来自字段表达式或常数,则不允许对视图执行INSERT 和UPDATE操作,但允许执行DELETE操作
  • 如果视图的字段来自聚合函数,则视图不允许更新
  • 创建视图的SELECT语句中使用分组子句GROUP BY,以及TOP、DISTINCT、UNION关键字时,视图不允许更新
  • 不能删除依赖于多个数据表的视图
  • 视图定义中如果有嵌套查询,且内层查询中涉及了与外层一样的导出该视图的基本表,则视图不能更新
  • 因为视图是从基本表导出的,所以对视图的插入、删除和更新操作必须遵守源基本表的完整性约束条件

② 使用视图更新数据

  • 由于视图不是实际存储的,是虚表,因此对视图的更新最终要转换为对基本表的更新
  • 为了防止用户通过视图对数据进行修改,无意或故意操作不属于视图范围内的基本数据,可在定义视图时加上with check option语句,这样在视图上进行数据更新时,DBMS会进一步检查视图定义中的条件,如果不满足,则拒绝执行该操作

二、数据查询语言DQL

1、select语句介绍

select [all|distinct] [top n[percent]] 目标列
[into 新表名]
from 表组
[where 筛选条件]
[group by<分组列名> [with{cube|rollup}]] [having <组选择条件>]
[order by[all] <排序列名>[asc|desc]]
  • select:写什么查询结果就显示什么。all是默认值,distinct去重,top n表示返回前n行,加上percent就是返回结果的前百分之n行
  • into:用于创建一个新表,将查询结果插入该新表中。如果select有计算数值的字段,必须指定别名
  • group by:当select后有统计函数,如果有group by,则统计为分组统计,否则是对整个结果集进行统计。group by后还可以跟having子句表达组选择条件,缩小查询范围
  • order by:对结果集进行排序。ASC升序排序,DESC降序排序

2、简单查询 

(1)查询表中的若干行

① top和distinct

【例1】查询借阅表的前4条记录信息

select top 4 *
from 借阅

【例2】查询借阅了图书的读者卡号(去重)

select distinct 读者卡号
from 借阅

② 查询满足条件的元组

【例3】查询清华大学出版社出版的计算机类或管理类图书信息

select *
from 图书
where 出版社='清华大学出版社' and 类别 in('计算机类','管理类')

select *
from 图书
where 出版社='清华大学出版社' and (类别='计算机类' or 类别='管理类')

③ 模糊查询

[not] like'<匹配串>'[escape '<换码字符>']

        查找指定的属性列值与匹配串相匹配的记录。匹配串可以是一个完整的字符串,也可以是含有通配符的字符串

通配符包含

  • %:表示任意长度的字符串(长度可以为0)
  • _:表示单个字符
  • [ ]:表示方括号内字符列表的任意一个字符
  • [^]:表示不在方括号内字符列表的任意一个字符
  • [-]:表示方括号内-范围内的任何一个字符,例如[A-D]
  • 如果用户要查询的字符串本身就有通配符,则用escape'换码字符'对通配符进行转义
  • 例:查询"DB_1",查询like 'DB/_1' escape' / ',说明跟在' / '后的'_'不再是通配符,而是普通字符

【例4】查询书名中包含"数据库"的图书信息

select *
from 图书
where 书名 like'%数据库%'

(2)对查询结果进行排序

  • asc:空值最先显示
  • desc:空值最后显示

【例1】查询出版日期在2014-05-01之后,书名第二个字为"理"的图书信息,按照出版日期降序、单价升序排序

select *
from 图书
where 书名 like '_理%' and 出版日期>'2014-05-01'
order by 出版日期 desc,单价

(3)汇总查询

① 聚合函数

常用聚合函数
函数名功能
count(*)返回表中所有总的数据记录个数,不管某列是否有空值
count([distinct | all] 列名)返回表中不是空值数据记录的个数
avg([distinct | all] 列名)返回列平均值
sum([distinct | all] 列名)返回列的总和
max(列名)返回列中最大值
min(列名)返回列中最小值

【例1】查询图书表中计算机类图书的总册数

select count(*) as 总册数
from 图书
where 类别='计算机'

② group by分类汇总

group by 分组列 [with{cube|rollup}]
[having 筛选条件表达式]
  • cube:执行各分组查询字段的小计或加总
  • rollup:执行针对第一个字段的加总
  • having:对生成的组筛选中后,再对满足条件的组进行统计,必须和group by配合使用

【例2】查询借阅图书超过1本的读者卡号和借书册数,要求只统计2014-11-01以后的借书情况

select 读者卡号,count(*) as 借书册数
from 借阅
where 借书日期>'2014-11-01' 
group by 读者卡号 having count(*)>1

执行顺序:

  • where先筛选掉不符合条件的记录
  • group by将剩余记录按指定列分组
  • having排除不符合条件的组
having和where的区别
wherehaving
作用于基本表或视图,在分组前选择满足条件的元组作用于组,在分组后对组进行筛选
不可用聚合函数可以用聚合函数
可以使用from所含表内所有属性只能使用select所含属性

【例3】在例2的情况基础上,对借书册数进行汇总

select 读者卡号,count(*) as 借书册数
from 借阅
where 借书日期>'2014-11-01' 
group by 读者卡号 with cube having count(*)>1

【例4】按年份统计每个读者的借书册数,并进行汇总

select 读者卡号,year(借书日期) as 年份,count(*) as 借书册数
from 借阅
group by 读者卡号,year(借书日期) 
with cube

group by子句可以是表名,也可以是表名表达式(year(借书日期)),但是不能是聚合函数

3、连接查询

(1)内连接 inner join

  • 定义:内连接是将多个表中共同列的值进行比较,把满足条件的记录横向连接起来作为查询结果,为默认连接方式
  • 实质:通过各表之间的共同列的关联来查询数据,连接条件通常是外键

① 等值连接

        等值连接包含两个表的全部属性,存在重复情况,就是单纯地将两个表连接起来

【例1】查询每个读者的情况和借阅情况

select 读者.*,借阅.*
from 读者 inner join 借阅 on 借阅.读者卡号=读者.读者卡号
  • 当查询引用多个表时,如果某列是多个表的相同列,则列名必须使用表名限定,无相同列名则省略表名限定。eg:借阅.读者卡号、读者.读者卡号

② 自然连接

        在等值连接基础上做到去重,则为自然连接

【例2】查询所有读者的姓名、性别、单位和读者所属的类别名称

select 姓名,性别,单位,读者.类别编号,类别名称
from 读者 inner join 读者类别 on 读者.类别编号=读者类别.类别编号

【例3】查询借阅了图书《微信公众号平台应用开发实战(第二版)》的读者姓名和所在单位

select 姓名,单位
from (图书 inner join 借阅 on 借阅.图书编号=图书.图书编号)
      inner join 读者 on 读者.读者卡号=借阅.读者卡号
where 书名='微信公众号平台应用开发实战(第二版)'

将第一个表和第二个表连接生成一个临时表,然后再连接第三个表

(2)外连接 outer join

  • 定义:如果要求查询结果集中保留非匹配的元组,外连接中不匹配的结果称为NULL

① 左外连接 left join

        查询结果集中保留连接表达式的左表中的非匹配记录,以及右表中符合条件的记录

【例1】查询读者姓名、单位、卡状态、借书日期和还书日期,要求查询结果也需要显示出没有借书的读者姓名、单位和卡状态

select 姓名,单位,卡状态,图书编号,借书日期
from 读者 left join 借阅 on 借阅.读者卡号=读者.读者卡号

左表:读者,右表:借阅

王武不满足连接条件,但作为左表,仍然输出

② 右外连接 right join

        查询结果集中保留连接表达式的右表中的非匹配记录,以及左表中符合条件的记录

③ 全外连接 full join

        两个表在连接过程中除了返回满足连接条件的行以外,还返回左表和右表中不满足条件的行

(3)自连接 self join 

  • 定义:自连接可以理解为自己连接自己,在一张表上面所进行的操作

【例1】查询在同一单位的读者卡号,读者姓名和单位

select distinct A.读者卡号,A.姓名,A.单位
from 读者 A inner join 读者 B 
on (A.读者卡号!=B.读者卡号 and A.单位=B.单位)

(4)交叉连接 cross join

  • 定义:交叉连接查询是笛卡尔积运算,查询结果的字段数=两表字段数总和
  • 去掉内连接的on后语句
select 读者.*,借阅.*
from 读者 inner join 借阅 

4、嵌套查询

(1)非相关子查询

  • 非相关子查询:子查询不依赖父查询,每个子查询只进行一次
  • 执行方式:先执行子查询,将子查询得到的结果集作为父查询的条件,进行父查询

① 用比较运算符的嵌套查询

【例1】查询办理借书卡比李丽晚的读者信息

select *
from 读者
where 办卡日期 >(select 办卡日期
                 from 读者
                 where 姓名='李丽')

② 用all、any运算符的嵌套查询

all、any与比较运算符结合的含义
操作符语义
>all大于子查询结果中的所有值(大于最大值)
>any

大于子查询结果中的某个值(大于最小值)

<all小于子查询结果中的所有值(小于最小值)
<any小于子查询结果中的某个值(小于最大值)
>=all大于等于子查询结果中的所有值(≥ 最大值)
>=any大于等于子查询结果中的某个值(≥ 最小值)
<=all小于等于子查询结果中的所有值(≤ 最小值)
<=any小于等于子查询结果中的某一值(≤ 最大值)
=all通常无意义
=any相当于in
!=(或<>)all相当于 not in
!=(或<>)any不等于子查询结果中的某一值

【例2】查询计算机类图书单价比管理类所有图书单价高的图书信息

select *
from 图书
where 单价>all(select 单价
               from 图书
               where 类别='管理')
and 类别='计算机'

③ 用in运算符的嵌套查询

【例3】查询借阅了图书《SQL入门》的读者姓名和单位

select 姓名,单位
from 读者
where 读者卡号 in(select 读者卡号
                  from 借阅
                  where 图书编号 in(select 图书编号
                                    from 图书
                                    where 书名='SQL入门'))

(2)相关子查询

  • 相关子查询:子查询的查询条件要依赖于父查询的元组值
  • 带有exist运算符的嵌套查询,子查询不返回任何数据,作用是用来检查子查询中是否有结果,如果有结果,父查询的where条件为true,否则为false
  • 相关子查询处理过程:
  1. 先取父查询的第一个元组
  2. 根据该元组值,执行子查询
  3. 根据子查询返回的值判断该元组是否加入结果集
  4. 直到父查询的表全部处理完
  5. 将结果集输出

【例1】查询借阅了图书编号为"GL0002"的图书的读者姓名

select 读者卡号,姓名
from 读者
where exists(select *
             from 借阅
             where 借阅.读者卡号=读者.读者卡号 and 图书编号='GL0002')

输出那些读者的读者卡号和姓名,当借阅表中存在他借阅了图书编号为GL0002图书的记录

由于子查询结果只返回true或false,因此子查询中select后通常是*

【例2】查询没有借阅图书编号为"GL0002"图书的读者姓名

select 读者卡号,姓名
from 读者
where not exists(select *
                 from 借阅
                 where 借阅.读者卡号=读者.读者卡号 and 图书编号='GL0002')
select Reader.dzkh,xm
from Reader inner join Borrow on Reader.dzkh=Borrow.dzkh
where tsbh!='GL0002'

【例3】查询借阅了全部图书的读者姓名

\forall y(P(x,y))\equiv \neg \exists y(\neg P(x,y))

查找这样的读者:不存在他没有借阅的书

select dzkh,xm
from Reader
where not exists(select *
				 from Book
				 where not exists(select *
								  from Borrow
								  where Borrow.dzkh=Reader.dzkh and Book.tsbh=Borrow.tsbh))

【例4】查询至少借阅了读者卡号为"1100001"读者所借阅的全部图书的读者姓名

转换:查询这样的读者:凡是1100001借阅的书,他都借阅了

\forall y(P(y)\rightarrow q(x,y))\equiv \neg \exists y( P(y)\rightarrow \neg q(x,y))

P(y)表示1100001借阅的图书y

q(x,y)表示读者x借阅的图书y

查找这样的读者:不存在1100001借阅的书,他没有借阅

select xm
from Reader
where not exists(select *
				 from Borrow A
				 where A.dzkh='1100001' and not exists
										(select *
									     from Borrow B
										 where B.dzkh=Reader.dzkh and B.tsbh=A.tsbh))

5、组合查询

(1)union并操作

【例1】查询借阅了图书编号为"JSJ001"或"GL0003"的读者卡号

select 读者卡号
from 借阅
where 图书编号='JSJ001'
union
select 读者卡号
from 借阅
where 图书编号='GL0003'

(2)intersect交操作

【例2】查询既借阅了图书编号为"JSJ001",又借阅了图书编号为"GL0003"的读者卡号,姓名,单位

select 读者.读者卡号,姓名,单位
from 读者 inner join 借阅 on 读者.读者卡号=借阅.读者卡号 and 图书编号='JSJ001'
intersect
select 读者.读者卡号,姓名,单位
from 读者 inner join 借阅 on 读者.读者卡号=借阅.读者卡号 and 图书编号='GL0003'
select 读者.读者卡号,姓名,单位
from 读者 inner join 借阅 on 读者.读者卡号=借阅.读者卡号 
and 图书编号='JSJ001'
and 读者.读者卡号 in(select 读者卡号
                    from 借阅
                    where 图书编号='GL0003')
select 读者卡号,姓名,单位
from 读者
where 读者卡号 in(select 读者卡号
                  from 借阅 A
                  where 图书编号='JSJ001'
                  and exists(select *
                             from 借阅 B
                              where A.读者卡号=B.读者卡号 and 图书编号='GL0003'))

(3)except差操作

【例3】查询没有借阅图书编号为"GL0002"图书的读者姓名

select 读者卡号
from 读者
except
select 读者卡号
from 借阅
where 图书编号='GL0002'

三、数据更新语言DML

1、插入数据

(1)插入单个元组

insert into 表名(属性列名1,属性列名2…)
values(常量1,常量2…)
  • into关键字和属性列表可有可无,且属性列不需要包含全部字段。
  • 可以省略列名,但必须保证values后的各数据项位置与表定义时的顺序一致,否则报错。
  • 如果给出表名后的属性列名,则表名后的属性名清单不需要和表结构的字段数目或顺序相同,但要和values子句的属性值顺序一致。
  • 如果只给出部分属性列名,则对于not null属性的字段必须列出属性列名,因为没有出现在子句中的属性将取空值,假如这些属性已定义为not null,将会出错。
  • 数据插入时,value子句中的属性值、字符与日期时间型数据需要使用单引号括起。如果对应属性列是默认值,可以使用default关键字;如果对应属性值是空值,直接使用null。

【例1】 向高校图书管理数据库的读者类别表中分别插入两条记录。

insert into 读者类别(类别编号,类别名称,可借阅天数,可借阅数量,超期罚款额)
values('01','教师',90,6,0.2)

insert into 读者类别
values('02','博士研究生',80,6,0.4)


【例2】向读者表插入三条记录

 

【例3】向图书表插入三条数据

(2)插入多个元组

① 行构造器

insert into 图书
values
('JSJ003','SQL Server 2012数据库应用与开发教程','计算机','卫琳','清华大学出版社','2014-08- 01 ',42,5),
('JSJ004','疯狂Java 讲义(第3版)','计算机','李刚','电子工业出版社','2014-07-01',109.00,5)

② insert/select命令

insert into 表名(属性列名)
<子查询>
  • 要求子查询的目标列和插入表的列数据类型要相同
  • 如果属性列的顺序、个数都相同,则可省略属性列名

【例1】把图书订购数据库中图书信息表(books)的数据记录插入高校图书管理数据库中的图书表中。

insert into 图书
select *
from 图书订购.dbo.books

        因为要访问的数据库对象图书信息表(books)与正在使用的数据库高校图书管理在同一台服务器上,但不在同一个数据库中,因此,引用图书信息表(books)时可以省略服务器名,但必须指定数据库名图书订购和架构名dbo。

【例2】 求每一类别图书的总册数,并把结果存入高校图书管理数据库中。

create table 图书类别库存量(类别nvarchar(40),总册数tinyint)
go
insert into 图书类别库存量
select 类别,SUM(库存数量)
from 图书
group by 类别
go

2、修改数据

(1)修改数据语法格式

update 表名
set 列名1=表达式,列名2=表达式…
[from 数据源]
[where 条件表达式]
  • where子句:指定要修改的记录需要满足的条件。如果没有where,则表示要修改指定表中的所有元组。where可以嵌入查询语句

(2)修改单个元组

修改单个元组,可以同时修改数据表中的多个属性列值


【例1】 在读者表中,修改读者卡号为“1100004”的记录,将卡状态的值改为挂失,将单位的值修改为全称“数学与计算机科学学院”。

update 读者
set 卡状态='挂失',单位='数学与计算机科学学院'
where 读者卡号='1100004'


【例2】 在【例1】的结果上,将读者卡号为“1100004”的读者单位修改为与读者卡号为“1100001”相同的单位名称。

update 读者
set 单位=(select 单位
          from 读者
          where 读者卡号='1100001')
where 读者卡号='1100004'

(3)修改多个元组

在实际业务中,有时需要同时修改整个表的某些属性列的值,或者是复合条件的某些属性列的值


【例3】 将读者表的办卡日期属性列的值统一修改为“2015-05-10”。

update 读者
set 办卡日期='2015-05-10'


【例4】 将读者赵亮所借图书的还书日期统一修改为“2015-03-10”。

update 借阅
set 还书日期='2015-03-10'
where 读者卡号 in(select 读者卡号
                  from 读者
                  where 姓名='赵亮')

此例也可以用下面的代码实现:

update 借阅
set 还书日期='2015-03-10'
from 借阅 inner join 读者 on 借阅.读者卡号=读者.读者卡号
where 姓名='赵亮'

update命令不仅可以更新同一个数据表的记录数据,使用JOIN命令就可以进行不同数据表的合并更新

3、删除数据

(1)delete

delete 
[from] 表名
[where 条件]


delete 表名
from 表名 连接另一表
[where 条件]

where子句:指定要删除的记录需要满足的条件。如果没有where,则表示要删除指定表中的所有元组。where可以嵌入查询语句

【例1】 删除书名为《请不要辜负这个时代》的图书信息。

delete
from 图书
where 书名='请不要辜负这个时代'


【例2】 删除读者杨少华的所有借阅记录。

delete 借阅
from 借阅 inner join 读者 on 借阅.读者卡号=读者.读者卡号
where 姓名='杨少华'

或使用以下的表示形式:

delete 借阅
from 借阅,读者
where 借阅.读者卡号=读者.读者卡号 and 姓名='杨少华'

或使用带有子嵌套查询的DELETE语句:

delete 借阅
where 读者卡号 in(select 读者卡号
                  from 读者
                  where 姓名='杨少华')

如果删除涉及多个表,则DELETE子句之后必须列出要删除数据所属的表名。
注意:DELETE语句删除的是表中的数据,而不是表的结构,即使表中的数据全部被删除,表的结构仍在数据库中。

(2)truncate

如果删除整个数据表,T-SQL语言中还提供了一个truncate table命令,用于删除数据表的所有记录。其语法格式如下:

truncate table 表名称

truncate table和delete的不同点:

  • truncate table删除记录的数据快,且不会将删除记录的操作写入事务日志,delete会写入事务日志。
  • truncate table删除完记录后,标识列会重新开始记数,而用delete语句删除之后,从上次最后记录为开始点继续记数。
  • 如果要删除记录的表是其他表外键指向的表,那么不能用runcate table语句删除,只能用delete。

4、数据更新操作检查完整性

(1)插入数据时需要分别检查实体完整性参照完整性

  • 检查实体完整性:若插入元组的主码值不为null,并且相应属性值在关系中不存在,则可执行插入操作,否则不执行
  • 检查参照完整性
  1. 若向参照关系中插入元组,则要检查外码值是否在被参照关系中存在对应的主码值,存在则插入,否则不执行插入操作
  2. 若要插入元组的外码允许为空,则外码是空值时插入
  3. 如果向被参照关系插入元组,则无法检查参照完整性
  • 注:外码——被参照关系的主码     主码——参照关系的主码

 

(2)删除数据时需要检查参照完整性

  • 如果删除的是参照关系的元组,则不需进行参照完整性检查,可执行删除操作
  • 如果删除的是被参照关系的元组,则检查被删除元组主码的属性值是否被参照关系中某元组的外码引用,未引用则删除,否则:
  • ① 不可执行删除操作,拒绝删除
  • ② 可删除,但需同时将参照关系中引用了该元组的对应元组一起删除,即执行级联删除
  • ③ 可删除,则需将参照关系的外码值置为null


(3)修改数据时需要检查实体完整性参照完整性

修改操作即先删除旧元组,再插入新元组,因此检查完整性同执行删除和插入操作

四、数据控制语言DML

1、数据控制方法

  • 授权定义
  • 存权处理
  • 查权操作

2、sql server数据库操作权限

  • 对象权限
  • select、insert、update、delete、execute
  • 系统权限
  • create database、create table、create view、create default……
  • 隐含权限

3、对象权限设置

grant/revoke/deny all|对象权限组 on 对象名
to|from 用户组|public
[with grant option]
  • grant:授予
  • revoke:回收、撤销
  • deny:取消
  • all:指所有的对象权限
  • to:在授予、拒绝访问权限时使用
  • from:在收回权限时使用
  • public:指数据库的所有用户
  • with grant option:指获得权限的用户可以把该权限再授予其他用户

【例1】授予用户user1图书表上insert、select权限,并允许他将得到的权限授予其他用户

grant select,insert on 图书 to user1 with grant option

4、语句权限设置

grant/revoke/deny 系统权限组
to|from 用户组|public
[with grant option]

【例2】把授予用户user2创建表的权限收回,授予除user3以外的其他所有用户创建视图的权限

revoke create table from user2

grant create view to public
deny create view to user3

五、数据库初步编程

1、变量

  • 全局变量:@@变量名,只能预先定义,不能修改
  • 局部变量:@变量名

(1)变量的声明

declare @变量名1 数据类型[=初值],@变量名2 数据类型[=初值]……

【例1】创建3个局部变量

declare @name varchar(10),@address char(30),@total int =1

(2)变量的赋值

① set赋值

set @变量名=表达式

【例2】将计算机类图书的库存总量赋给变量total,并使用print显示变量值

declare @total tinyint
set @total=(select sum(库存数量)
            from 图书
            where 类别='计算机')

print'库存总量:'+cast(@total as char)

② select赋值

【例3】将读者表中女读者的姓名和单位的域值存入局部变量中

declare @myname nvarchar(16),@mydepat nvarchar(30)
select @myname=姓名,@mydepat=单位
from 读者
where 性别='女'

select @myname as 姓名,@mydepat as 单位

③类型转换函数

cast(表达式 as 数据类型)

convert(数据类型[长度],表达式)

2、流程控制

(1)begin end

相当于c语言中的{}

(2)if else

【例1】统计读者卡号为“1100002”的读者的借书数目,如果不少于两本就显示“你借阅了×本图书,很好,祝你阅读愉快!”,否则显示“你借阅了×本图书,借书有点少,请多提宝贵建议!”(其中×表示借书数目)

DECLARE @cn smallint,@text varchar(100)

SET @cn=(SELECT COUNT(图书编号)
         FROM 借阅
         WHERE 读者卡号='1100002')

IF @cn>=2
    BEGIN
        SET @text='你借阅了'+CAST(@cn AS char(2))
        SET @text=@text+'本图书,很好,祝你阅读愉快!'
    END
ELSE
    BEGIN
        SET @text='你借阅了'+CAST(@cn AS char(2))
        SET @text=@text+'本图书,借书有点少,请多提宝贵建议!'
    END

SELECT @text AS 借书提示信息

(3)while

(4)case

【例2】 使用CASE 函数根据读者“类别编号”判断读者所属的读者类别名称。

SELECT 读者卡号,姓名,
    CASE类别编号
        WHEN '01'THEN '教师'
        WHEN '02'THEN '博士研究生'
        WHEN '03'THEN '硕士研究生'
        WHEN '04'THEN '本科生'
        ELSE '没有录入'
    END AS 读者所属类别
FROM 读者

【例3】 统计不同类别图书的平均单价及评价信息,评价信息用贵、稍贵、可以接受、便宜、非常便宜表示,要求统计结果以平均单价的降序进行排序。当平均单价大于等于50,评价为“贵”;当平均单价大于等于40 小于50,评价为“稍贵”;当平均单价大于等于30小于40,评价为“可以接受”;当平均单价大于20 小于30,评价为“便宜”;否则评价为“非常便宜”。

SELECT 类别,STR(AVG(单价),4,1) AS '平均单价',
    CASE
        WHEN AVG(单价)>=50 THEN '贵'
        WHEN AVG(单价)>=40 THEN '稍贵'
        WHEN AVG(单价)>=30 THEN '可以接受'
        WHEN AVG(单价)>=20 THEN '便宜'
        ELSE '非常便宜'
    END AS '评价信息'
FROM 图书

GROUP BY 类别
ORDER BY 平均单价 DESC

将数值转换为字符str函数

str(表达式,字符串总数,小数保留位)
  • 表达式是一个带小数点的近似数字数据类型的表达式
  • length表示总长度(总长度包括小数点、符号、数字以及空格)
  • decimal 指定小数点后的位数

(5)waitfor

waitfor delay|time
  • DELAY:指定必须延迟的一段时间,例如10s,最长可为24h
  • TIME:指定运行程序的时间点,例如上午10点

        用来暂时停止批处理、存储过程或事务等程序的执行,直到所设定的等待时间已过或所设定的时刻快到,才继续往下执行。延迟时间和时刻的格式为“HH:MM:SS”

【例4】延迟10s后查询图书表

waitfor delay '00:00:10'
select *
from 图书

(6)goto

        GOTO关键字可以更改执行流程到指定的标签处,跳过GOTO后面的T-SQL语句,并从标签位置继续处理。GOTO可在程序中的任何位置使用。其语法格式如下:

标签名称:
<语句组>
GOTO 标签名称
  • 使用GOTO 跳转时,需要指定跳转标签的名称。标签的定义可在GOTO之前或之后,标签名称可以是数字和字符的组合,但必须以“:”结尾。
  • GOTO关键字最常用在跳出嵌套循环,因为BREAK 只能跳出本层WHILE 循环,如果需要跳出整个嵌套循环,则需使用GO关键字。

(7)注释

  • 多行注释格式:/*注释语句*/
  • 单行注释格式:--注释语句

3、存储过程编程

  存储过程是为了实现特定任务,而将一些需要多次使用的、能够完成特定功能的操作语句编写成SQL语句的集合,该集合编译后放在数据库服务器上,用户应用程序通过指定存储过程的名称来调用并执行存储过程中的语句。
  也就是说,存储过程是被存储在数据库中的可以接受和返回用户提供参数的SQL程序,在创建时被编译和优化,创建后可被程序调用。

(1)创建存储过程

create procedure <存储过程名>
[{@参数名数据类型}][=默认值][output]
[with {recompile|encryption}]
as 
    T-SQL语句块
go
  • @参数名:在创建存储过程时可以声明一个或多个参数。参数包括输入和输出参数,输入参数提供执行存储过程所必需的变量值,输出参数用于返回执行存储过程后的一些结果值。参数实质是局部变量,只在声明的存储过程内有效。
  • output:输出参数,在存储过程退出后,output值将返回调用程序,以便在调用该存储过程的程序中获得并使用该参数值。
  • with recompile:每次执行时都对其进行重新编译。有时修改了存储过程中使用的数据对象,若直接运行之前已编译好的存储过程,可能会出现运行错误,为了避免此类情况的发生,使用recompile,但降低了执行速度。
  • with encryption:对创建的存储过程文本进行加密,防止他人查看或修改。
  • as:指定该存储过程要执行的操作。
  • T-SQL语句块:用于定义存储过程执行的各种类型的T-SQL语句。

(2)执行存储过程

execute 存储过程名
[@参数名=]参量值|@变量

(3)存储过程应用实例

【例1】创建一个名为 pro_dzjy 的存储过程,查询每个读者借阅图书的信息,包括读者卡号、图书编号、书名、借书日期。

create procedure pro_dzjy
AS 
select 读者卡号,借阅.图书编号,书名,借书日期
from 图书 inner join 借阅 on 借阅.图书编号=图书.图书编号
go

【例2】创建一个名为proc_tsxx的存储过程,用于根据出版社和图书类别查询图书信息,并利用该存储过程查询清华大学出版社出版的计算机类的图书信息。

create procedure proc_tsxx
    @cbs nvarchar(20),    --输入参数
    @tslb nvarchar(16)
as
    select *
    from 图书
    where 出版社=@cbs and 类别=@tslb
go
exec proc_tsxx '清华大学出版社','计算机'
  • 调用存储过程时,可以不给出参数名,但参数值必须和定义参数的顺序一致。
  • 如果不按照定义的参数顺序传递参数,则要指定参数名。
exec proc_tsxx @tslb='计算机类',@cbs='清华大学出版社'

【例3】输入某个读者的读者卡号,统计该读者的借书册数,并返回该读者的姓名和借书册数。

create procedure proc_dzjstj
	@dzkh char(10),    --输入参数
    @dzxm char(16) output,       --输出参数
    @jscs tinyint output
as begin
	select @dzxm=xm
	from Reader
	where dzkh=@dzkh

	select @jscs=count(*)
	from Borrow
	where dzkh=@dzkh
	group by dzkh
end
go

declare @xm varchar(16),@cs tinyint    --output参数必须指定变量来接收
exec proc_dzjstj '110002',@xm output,@cs output    --dzkh是输入变量,xm和cs都是输出变量

print'姓名为'+@xm+',借书册数为'+str(@cs)

(4)删除和修改存储过程

drop procedure 存储过程名

alter procedure 存储过程名

4、触发器编程

(1)DML触发器

DML触发器是当执行insert、update、delete时,一种自动执行的触发器。

① 创建DML触发器

create trigger 触发器名称 on 表名|视图名
[with encryption]
for|after|instead of
[insert,][update,][delete]

as
    if update(列)
    T-SQL语句
  • 表 | 视图:指定操作的对象为表或视图,视图只能被instead of触发器引用
  • with encryption:对创建的触发器文本进行加密。
  • for | after:指定触发器只有在触发事件包含的所有操作都已成功执行后才被激活。如果仅指定for关键字,则after是默认设置。
  • instead of:即用触发器程序取代相应的操作,当对表或视图执行instead of后面指定的操作时,仅执行触发器程序。此功能主要用于使不能更新的视图支持更新。
  • [insert][,][update][,][delete]:指定在表或视图用于激活触发器的操作类型,必须至少指定一个选项。在触发器定义中允许使用以任意顺序组合的多个选项。如果指定的选项多于一个,需要用逗号分隔。
  • update(列):在触发器程序中被用来判断哪些列被修改(INSERT和UPDATE)。
  • T-SQL语句块:用于定义触发器执行的各种类型的T-SQL语句。

② DML触发器工作原理

一个触发器只适用于一个表,每个表最多只能有3个触发器,分别是insert、delete、update

在创建DML 触发器的语句中可以使用两个特殊的表:

  • inserted 表(插入的表)
  • deleted 表(删除的表)

        SQL Server会自动创建和管理这两种表,这两张表是逻辑表,是只读的,驻留在内存而不是存储在数据库中,并且由系统管理的。不允许对其修改,两个表的结构总是与被该触发器作用的表的结构相同,当触发器工作完成,两个表也被删除

  • inserted 表用于存储insert和update语句所影响的行的副本
  • deleted 表用于存储delete和update语句所影响的行的副本

  INSERT 触发器:当执行insert操作时,先向inserted 表中插入一个新行的副本,然后检查inserted 表中的新行是否有效,确定是否要阻止该插入操作。如果所插入的行中的值是有效的,则将该行插入到触发器表。
  UPDATE触发器:当执行update操作时,先将旧数据行保存到deleted表中,然后将新数据插入inserted 表中,最后计算deleted 表和inserted表中的值以确定是否进行干预。
  DELETE触发器:当执行delete操作时,将旧数据行移到deleted 表中,计算deleted表中的值决定是否进行干预,如果不进行干预,则删除数据行。

③ DML触发器应用实例

【例1】创建触发器,保证读者表中性别只能为男或女

分析:因为破坏约束"性别只能为男或女"的操作是插入和修改操作,因此需要建立insert和update两个触发器,如果在inserted表中有性别取值不为男或女的记录,取消本次操作

create trigger tri_t1 on 读者
for insert,update
as
    if exist (select *
              from 读者
              where 性别 not in('男','女'))
     begin
        print '读者性别必须为男or女'
        rollback
     end

【例2】利用触发器保证删除读者记录的同时,也要把相应的借阅记录删除。

create trigger tri_t2 on 读者
for delete
as 
    if(select count(*)
       from 借阅,deleted
       where 借阅.读者卡号=deleted.读者卡号)>0
    begin
        delete 借阅
        from 借阅 inner join deleted on 借阅.读者卡号=deleted.读者卡号
    end

只有在成功执行触发T-SQL语句之后,才会激活AFTER触发器
以删除表中记录为例,整个执行分为如下步骤。

  • 当系统接收到一个要执行删除读者表中的记录的T-SQL语句时,系统将要删除的记录存放在deleted表中。
  • 把读者表中的相应记录删除。
  • 删除操作激活了事先编制的AFTER触发器,系统执行AFTER触发器中AS定义后的T-SQL语句。
  • 触发器执行完毕后,删除内存中的deleted表,退出整个操作。若触发器语句执行失败,则整个过程回滚,恢复到初始状。


【例3】 图书表中的图书编号是唯一且不可改变的,创建触发器,实现更新图书编号的不可改变性。

CREATE TRIGGER tri_t3 ON 图书
FOR UPDATE
AS
    IF UPDATE(图书编号)
        BEGIN
            PRINT'每一个图书编号是唯一的,不能改变'
            ROLLBACK TRANSACTION
        END


【例4】 使用触发器实现当向借阅表中新增一条借阅记录时,更新图书表中对应图书的库存量的值。

CREATE TRIGGER tri_t4 ON 借阅
FOR INSERT
AS
    BEGIN
        UPDATE 图书
        SET 库存数量=库存数量-1
        WHERE 图书编号=(SELECT 图书编号
                        FROM inserted)
    END


【例5】 为读者类别表创建一个INSERT操作类型的触发器。当插入的新行中“类别名称”的值是“专科生”时,就撤销该插入操作,并使用RAISERROR 语句返回一个错误信息。

CREATE TRIGGER tri t5 ON 读者类别
FOR INSERT
AS
    DECLARE @lbmc char(10) --声明变量
    SELECT @lbmc=类别名称
    FROM inserted --获取新数据行类别名称的值

    IF @lbmc='专科生'
        BEGIN
            ROLLBACK TRANSACTION --撤销插入操作
            RAISERROR('不能插入专科生的读者信息!',16,10)   --RAISERROR语句返回错误信息
        END

(2)DDL触发器

DDL 触发器是在执行DDL 命令(create、alter、drop、grant、revoke 等)后触发执行的,所以不能创建类似于DML触发器的INSTEAD OF 触发器

① 创建DDL触发器

create trigger 触发器名
on {all 服务器|数据库}{for|after}
{事件类型}
as
    T-SQL语句
  • ALL服务器:是指将DDL触发器作用到整个当前的服务器上。如果指定了这个参数,在当前服务器上的任何一个数据库都能激活该触发器。
  • 数据库:数据库表示将DDL 触发器作用域应用于当前数据库,只能在当前数据库上激活该触发器。
  • FOR或AFTER:是同一个意思,可以指定FOR,也可以指定AFTER,DDL触发器不能指定INSTEAD OF触发器。
  • 事件类型:指可以激发DDL触发器的事件,主要是以create、alter、drop开头的T-SQL语句。

使用DDL触发器的时机如下所示:

  • 保护数据库模式不会改变。
  • 记录数据库模式的改变或相关事件。
  • 希望在更改数据库模式时,有一些响应来进行额外处理。

② DDL触发器实例

【例1】创建一个名为tri t6的触发器,当创建数据库时,系统返回提示信息“DATABASE CREATED”。

CREATE TRIGGER tri_t6 ON ALL SERVER
FOR CREATE_DATABASE
AS
    PRINT 'DATABASE CREATED'

成功运行创建触发器后,执行如下测试语句:
CREATE DATABASE xx
消息栏内会出现设计的“DATABASE CREATED”。


注意:系统不会为DDL 触发器创建inserted 表和deleted 表。

(3)删除和修改触发器

delete trigger 触发器名称

六、嵌入式SQL

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642733.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

东北小胖丫华夏受邀拍摄“沈水之阳,我心向往,寻美沈阳”宣传片

6月1日-4日&#xff0c;东北小胖丫华夏带领华夏星闪闪爱心公益服务队的小志愿者们&#xff0c;在沈阳的地标性建筑——沈阳故宫、中街、五里河公园等地&#xff0c;拍摄了“寻美沈阳”宣传片。 宣传片以“沈水之阳&#xff0c;我心向往&#xff0c;我爱沈阳&#xff0c;我爱家乡…

希尔贝壳邀您参加2023深圳国际人工智能展览会

2023深圳国际人工智能展览会“AIE”将于2023年5月16-18日在深圳国际会展中心 (宝安)举办&#xff0c;希尔贝壳受邀参加&#xff0c;展位号&#xff1a;A331。 伴随着智能行业的快速发展&#xff0c;展会已被越来越多的企业列入每年必选展会&#xff0c;也成为各采购商选购的理…

互联网 Java 高级工程师面试 1000 题 + 答案汇总(社招最新版)

作为一个 Java 程序员&#xff0c;你平时总是陷在业务开发里&#xff0c;每天噼里啪啦忙敲着代码&#xff0c;上到系统开发&#xff0c;下到 Bug 修改&#xff0c;你感觉自己无所不能。然而偶尔的一次聚会&#xff0c;你听说和自己一起出道的同学早已经年薪 50 万&#xff0c;而…

web期末大作业--网页设计 HTML+CSS+JS(附源码)

目录 一&#xff0c;作品介绍 二.运用知识 三.作品详情 四.部分作品效果图 我的&#xff1a;​编辑 五.部分源代码 六.文件目录 七.源码 一&#xff0c;作品介绍 作品介绍&#xff1a;该作品是一个是一个关于影视作品的网页&#xff0c;一共有五个页面&#xff0c;主页&a…

安全狗(云)工作负载安全保护解决方案护航电信运营商多云环境下的数字安全

随着互联网技术的发展&#xff0c;云计算、大数据、物联网、微服务、容器等新技术的尝试和应用&#xff0c;基础设施架构呈现出更加“混合化”的趋势&#xff0c;虚拟化、微服务、容器等工作负载成为了新的业务载体。 一 保护&#xff08;云&#xff09;工作负载安全迫在眉睫…

迪赛智慧数——柱状图(极坐标扇图):我国民众普遍面临的睡眠问题

效果图 常见的睡眠问题&#xff0c;你占了哪一样? 在网络科技发达的今天&#xff0c;伴随着高压快节奏的生活状态&#xff0c;各阶层各年龄段的睡眠问题接踵而至&#xff0c;甚至只增不减&#xff0c;一觉到天亮的好睡眠变得无价。据最新睡眠报告数据显示&#xff0c;75%的受…

华为OD机试真题 JavaScript 实现【最多提取子串数目】【2023Q1 100分】

一、题目描述 给定由[a-z] 26 个英文小写字母组成的字符串 A和 B&#xff0c;其中A中可能存在重复字母&#xff0c;B 中不会存在重复字母&#xff0c;现从字符串 A 中按规则挑选一些字母&#xff0c;可以组成字符串 B。 挑选规则如下: 同一个位置的字母只能被挑选一次&#…

快速上手Opencv:HighGUI图形用户界面

HighGUI图形用户界面 1.图像的载入、显示和输出到文件 1.1 图像的载入&#xff1a;imread()函数 Mat imread(const string &filename,int flags1) 第一个参数&#xff1a;图片路径第二个参数&#xff1a;载入标识&#xff0c;指定一个加载图像的颜色类型。可以看到它自…

解决@Transactional事务不回滚问题

1、事务不回滚情况 - 演示 1.1 情况说明&#xff1a; service层加了事务管理器Transactional &#xff0c;报错后&#xff0c;事务并没有同时回滚&#xff1b; service层调用了两个dao层的方法&#xff0c;执行第一个dao层方法&#xff0c;正常往数据库插入数据。执行第二个d…

selenium4-获取页面元素相关信息

引言 现在&#xff0c;越来越多的公司和企业开始将业务转移到线上平台。而对于网站或者应用的测试、开发人员来说&#xff0c;获取页面元素相关信息是解决很多问题的关键之一。 如果您正为此而苦恼&#xff0c;那么恭喜您&#xff0c;因为这篇文章将会为您揭秘Selenium4获取页…

HAProxy概述、搭建Web群集

HAProxy概述、搭建Web群集 一、HAProxy概述1、HAProxy的主要特性2、常见的Web集群调度器3、Haproxy应用分析4、Haproxy调度算法原理 二、LVS、Nginx、HAproxy的区别三、LVS、Nginx、HAproxy的优缺点1、Nginx的优点&#xff1a;2、Nginx的缺点&#xff1a;3、LVS的优点&#xff…

数据抓取,驱动商业智能的密码|HTTP代理的应用

在信息爆炸的时代&#xff0c;数据无疑成为了推动行业发展的重要动力。而数据抓取作为一种强大的工具&#xff0c;已经成为众多行业的秘密武器&#xff0c;为商业决策提供了前所未有的洞察力和竞争优势。让我们揭开数据抓取的神秘面纱&#xff0c;探索它在各个行业中的高级应用…

SpringCloud microservice-student-provider-1001服务提供者项目建立(三)

新建一个服务器提供者module子模块&#xff0c;类似前面建的common公共模块&#xff0c;名称是 microservice-student-provider-1001 pom.xml改成&#xff1a; <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSc…

go/go-pg插入time.Time字段为date类型时值自动变化的问题

今天偶然间发现一个问题&#xff0c;基于go-pg框架插入数据时&#xff0c;时间值自动减了1天。 目录 背景 现象与场景还原 问题解决与总结 背景 结构体中包含时间列类型&#xff0c;列类型是Date&#xff0c;对应的结构体类型是time.Time&#xff0c;此时对此对象做插入操…

Segment Anything使用手册(交互式数据标柱|自动数据标柱)

主要内容包含segment-anything项目的安装、基于SamPredictor对单点输入生成mask、基于SamPredictor对多点输入生成mask、基于SamAutomaticMaskGenerator自动生成mask。 Segment Anything项目是一个可以对任何图像进行分割的项目&#xff0c;其论文介绍可以查看https://blog.cs…

【JavaWeb】Cookie和Session的使用场景分析与应用

哈喽&#xff0c;大家好~我是你们的老朋友&#xff1a;保护小周ღ Cookie 和 Session 都是网页中常用的状态保持的技术&#xff0c;它们可以帮助网站识别用户身份&#xff0c;保存用户状态等&#xff0c;什么是 Cookie &#xff1f;什么是 Session &#xff1f;他们具体是什么…

Docker部署SonarQube代码质量检查平台+PostgreSQL数据库

一、安装PostgreSQL11(PostgreSQL7.9之后不支持MySQL) 检查代码的时候&#xff0c;仓库或者本地的代码会全部存储到postgresql数据里中&#xff0c;所以容量尽量大点&#xff0c;我这给个300G 指定拉取postgres11版本&#xff0c;不要postgres:latest&#xff0c;因为你部署so…

命令行创建uniapp项目

命令行创建uniapp项目 除了使用HBuilderX工具可视化搭建项目外&#xff0c;DCloud官方还提供了一个脚手架用于命令行搭建项目。 环境安装 全局安装vue-cli npm i vue/cli4 -g建议使用vue-cli 4.x版本&#xff0c;vue-cli 5.x与webpack存在冲突&#xff0c;会导致运行报错 …

聘准备-数据科学家

https://www.zhihu.com/question/21592677/answer/786529944

爆肝整理,性能测试-负载测试总结,你不知道的都在这了...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试中最容易…