SQL Server的高级知识

DataSet的内容介绍,两种单例模式(并发量的考虑),SQL高级中的case语句、连接操作、子查询、派生表

————————————————————————————————

1.Case的用法

使用方法一:(类似C#中的case的用法)

->语法:

Case  表达式

when 值1 then 返回值

when 值2 then 返回值

End

->案例:把用户表中数据,全部查询出来,要求把DelFlag=0的显示成未删除

select *,case DelFlag

when 0 then N‘未删除‘

when 1 then N‘删除‘

end as 删除状态

,UserName

from

UserInfo

使用方法二:(类似C#中的多个if else)

->语法

Case

when 表达式 then 返回值

when 表达式 then 返回值

else 值

->案例:把用户表中数据全部查询出来,要求把DelFlag=0的显示成删除

select *,case

when DelFlag=0 then N‘未删除‘

when DelFlag=1 then N‘删除‘

else N‘未知‘

end as 删除状态

,UserName

from

UserInfo

2.补充:ISNULL(表达式,替换的值)

select CreateDate,ISNULL(CreateDate,getdate()) from UserInfo

3.SQL控制语句

->SQL中的变量

->定义变量:

->declare @变量名 变量类型

->给变量赋值:

->set @参数名=值

->select @参数名=值

select @i=count(1) from UserInfo;

->打印 : Print @变量名

->IF ELSE

->语法格式:

if(表达式)

begin

SQL语句

end

else

begin

语句

end

->WHILE

->语法:

While(表达式)

begin

SQL语句

end

4.数据的连接

主键不参与业务逻辑

->交叉连接

一张表中有M条数据,另一张表中有N条记录,那么交叉连接后就是M*N

->内连接

一张表中有M条数据,另一张表中有N条记录,那么内连接后的数据不确定条数,要根据外键去讨论

->外连接

select * from 表1 as t1 right jion 表2 as t2 on t1.列名=t2.列名;

表示将表1和表2通过“列名”作为对应关系进行连接,如果有数据没有相关对应,就看中间的连接方式right/left/full,如果是right就以右侧的数据为主,如果是left就以左侧的数据为主,如果是full就全部都显示,没有对应就补null;

5.子查询

需要将一个一个查询的结果作为另一个查询的条件

通常,将里面的查询叫做子查询,外面的查询叫做外部查询

注意:子查询内部 必须查询一个数据

返回结果

单值(一个单元格)    标量子查询(常常放在where子句中作为条件,或者在select中作为一个值)

多值    多值子查询

行(略)

列    一般放在in中作为批量删除、修改等操作或查询

表    一般作为数据源进行再一次检索

6.表表达式

->派生表

select top 30

t1.stuId as 编号

, t1.stuName as 姓名

, case t1.stuSex when ‘m‘ then ‘男‘ else ‘女‘ end as 性别

, t3.final as 期末总评

, t2.className as 课程

, t1.stuPhone as 电话

, t1.stuAddress as 家庭住址

from

TestDataBase..Student as t1

inner join

TestDataBase..Course as t2

on t1.classId = t2.classId

inner join

(select

stuId

, avg(testBase+testBeyond+testPro) as final

from

TestDataBase..Score

group by

stuId) as t3

on t1.stuId = t3.stuId

order by

t3.final desc;

其中,将结果集作为一张表来使用的应用就叫做派生表

实际上这张表是不存在的,

汇编语言:机器型语言

高级语言:描述性语言

第三种语言:任务型语言

表表达式的意思是表参与运算得到的结果还是表,常用的表表达式:

->派生表

->分页(重要)

引出:淘宝京东购物网站,第一页显示不了 ,会分页显示

select * from Student;

一共有6万条数据,一次显示会崩溃,所以分页显示

问题:每页有M条记录,要显示第N页,如何实现?

其实不好写,凡是遇到这种有规律性问题的时候,你需要给自己设置具体的数字,按照数字的规律先写个三遍、四遍的结果,从中找到结果;

每页10条,第1页

select top 10 * from TestDabase..Student;

每页10条,第2页

select * from TestDatabase..Student where stuId between 11 and 20;

每页10条,第3页

select * from TestDatabase..Student where stuId between 21 and 30;

……

规律:

每页M条,第N页

select * from TestDatabase..Student

where stuId between M*(N-1) and M*N;

如果不连续,那么可以考虑加一个列,让其连续

--row_number() over(order by 字段)

->公用表表达式(CTE)

-- 公用表表达式(CTE common table expression)

-- 语法

/*

with 别名

as

(

结果集

)

紧跟查询

*/

with t

as

(

select

row_number() over(order by stuid) as num

, stuId

, stuName

, stuSex

, stuBirthdate

, stuStudydate

, stuAddress

, stuEmail

, stuPhone

, stuIsDel

, stuInputtime

, classId

from

TestDataBase..Student

where

stuIsDel = 0

)

select -- 紧跟查询

num

, stuId

, stuName

, stuSex

, stuBirthdate

, stuStudydate

, stuAddress

, stuEmail

, stuPhone

, stuIsDel

, stuInputtime

, classId

from t

where t.num between (10-1)*9+1 and 9*10;

->视图(View)

可持久化的派生表

create view vw_FenYeable    --视图名需要以vw开头

因为必须是批处理执行的语句 ,所以需要在首尾加go

go

create view vw_FenYeable

as

select

row_number() over(order by stuid) as num

, stuId

, stuName

, stuSex

, stuBirthdate

, stuStudydate

, stuAddress

, stuEmail

, stuPhone

, stuIsDel

, stuInputtime

, classId

from

TestDataBase..Student

where

stuIsDel = 0

go

select * from vw_FenYeable where vw_FenYeable.num between 9 * 10 + 1 and 10 * 10;

--视图无法存储数据,本质上还是查询,目的是更好的帮助我们进行查询。如果每次查询一个复杂操作的时候,选择使用视图

->内联表值函数(*不做要求)

-- 就是带有参数的“视图”

-- 语法

/*

create function fn_函数名

(@参数名 as 类型, @参数名 as 类型, ...)

returns table

as

return

结果集

*/

定义时:

go

create function fn_FenYe

(@pageCount as int, @pageIndex as int)

returns table

as

return

select

num

, stuId

, stuName

, stuSex

, stuBirthdate

, stuStudydate

, stuAddress

, stuEmail

, stuPhone

, stuIsDel

, stuInputtime

, classId

from vw_FenYeable

where

vw_FenYeable.num

between (@pageIndex - 1) * @pageCount + 1 and @pageCount * @pageIndex;

go

使用时:

select * from fn_FenYe(20, 9);

-- 将结果集进行运算,得到一个新的结果集,并将其作为数据源进行查询

7.表的透视变换

将原始给的横表显示成竖排方式:

select

学号

, sum(case when 课程=‘语文‘ then 成绩 else 0 end) as ‘语文‘

, sum(case when 课程=‘数学‘ then 成绩 else 0 end) as ‘数学‘

, sum(case when 课程=‘英语‘ then 成绩 else 0 end) as ‘英语‘

from

Score

group by 学号

8.事务

在SQL Server中,默认的每一条语句都是一个事务 。

begin transaction

事务内容

->生效

commit transaction

->不生效

rollback transaction

如何知道事务是否生效?

@@rowcount    记录上条语句受影响的行数

@@error    如果有错记录错误编码

事务:一个整体,要么全部执行成功,要么全部执行失败

严格的定义:如果一个操作满足原子性、持久性、隔离性与一致性,那么这个操作称为一个事务

原子性:不可划分,要么全部成功要么全部失败

持久性:一旦事务执行完成,不可销毁

隔离性:如果事务在执行操作时还未完成,另外一个事务需要执行这个操作相关时需要等待(阻塞)

一致性:一旦事务完成,不管在文件中、数据文件中、内存中的所有数据都是一样的

如果严格遵循事务的操作,会很影响性能但是提高安全性

->隔离性的实现机制:锁

数据文件分块存储 文件存储模型:文件块

颗粒度:是锁定一行数据还是锁定一页数据就叫做颗粒度

共享锁(读)、排他锁(增删改)

->事务隔离级别

未提交读、已提交读、可重复读、序列化读、快照

9.存储过程    procedure

将SQL语句封装起来,就像C#中的方法一样

意义:将一个执行的过程(可能会很复杂)封装成一个名字,然后使用这个名字就可以执行这个过程

语法:

create peoc[edure] 存储过程名字

参数 as 类型 [默认值|output]    --此处的as可以省略

as

begin

代码

end

e.g.

go

create proc usp_test1

as

begin

begin transaction

declare @myError int;

update bank set balance=balance - 900 where cid=‘0002‘

set @myError = (select @@ERROR);

update bank set balance=balance + 900 where cid=‘0001‘

set @myError += (select @@ERROR);

if(@myError = 0)

begin

commit

end

else

begin

rollback

end

end

go

->执行存储过程

exec usp_test1;

->带参数的存储过程

go

create proc usp_test2

@from as char(4)

, @to as char(4)

, @money as money

as

begin

begin transaction

declare @myError int;

update bank set balance=balance - @money where [email protected]

set @myError = (select @@ERROR);

update bank set balance=balance + @money where [email protected]

set @myError += (select @@ERROR);

if(@myError = 0)

begin

commit

end

else

begin

rollback

end

end

go

->执行

exec usp_test2 ‘0001‘, ‘0002‘, -900;

exec usp_test2 @to=‘0002‘, @money=100, @from=‘0001‘;

->上述执行是否成功不能看到,需要有返回值的存储过程

go

create proc usp_test3

@from as char(4)

, @to as char(4)

, @money as money

, @isSuccess int output -- 与C#一模一样,在存储过程内部赋值即可

as

begin

begin transaction

declare @myError int;

update bank set balance=balance - @money where [email protected]

set @myError = (select @@ERROR);

update bank set balance=balance + @money where [email protected]

set @myError += (select @@ERROR);

if(@myError = 0)

begin

commit

set @isSuccess = 1;

end

else

begin

rollback

set @isSuccess = 0;

end

end

go

->执行

但是这里虽然能显示我们的结果,但是如果出错结果为0但是还是会报错,怎么才能让它不报错呢?

->在SQL Server中的Try-catch

go

create proc usp_test4

@from as char(4)

, @to as char(4)

, @money as money

, @isSuccess int outputas

begin

begin transaction

begin try

update bank set balance=balance - @money where [email protected]

update bank set balance=balance + @money where [email protected]

commit

set @isSuccess = 1;

end try

begin catch

rollback

set @isSuccess = 0;

end catch

end

go

存储过程是为了用一个名字代替一串Sql语句,传输会快,解析不需要也会快

所以不管是大公司还是小公司都会用存储过程,但是也有的公司会要求全部用C#的逻辑来写

->系统存储过程

exec sp_help;

->默认参数的存储过程

go

create proc usp_FenYe1

@pageIndex int = 1        -- 第几页

,@pageCount int = 10-- 每页条数

as

begin

select * from fn_FenYe(@pageCount, @pageIndex);

end

go

10.触发器

现在来讲,用触发器的机会还不多

触发器是什么?

是一个特殊的存储过程,如果用C#来比喻的话本质还是方法

不是自己调用,而是因为执行某一个错做二自动的触发,就像事件

使用

->监视操作

(可以记录操作的时间、人物……)

->补充约束

(约束只能在一张表里,如果跨越多张表还要对字段进行约束的话可以考虑进行约束)

->语法

create trigger tr_类型_触发器的名字 on 表名

触发类型:after(之前)|instead of(代替,一般不用)

操作类型:insert|delete|update

as

begin

代码

end

两张临时表

inserted和deleted

11.逻辑与流程控制

-- 逻辑处理与流程控制

-- 选择结构

/*

if        表达式

begin

end

else if        表达式

begin

end

else

begin

end

*/

-- 循环结构

/*

while 表达式

begin

end

*/

-- 定义变量

declare @num int;

-- 为变量赋值

set @num = 123;

-- 使用

select @num;

-- 求1到100的和

declare @sum int;

declare @i int;

set @sum=0;

set @i = 0;

while @i <= 100

begin

set @sum = @sum + @i;

set @i = @i + 1;

end

select @sum;

go

declare @sum int;

declare @i int;

set @sum=0;

set @i = 0;

while @i <= 100

begin

if @i % 2 = 0

begin

set @sum = @sum + @i;

end

set @i = @i + 1;

end

select @sum;

go

-- 系统变量常常使用@@来引导

select @@VERSION

select @@ERROR;

时间: 2024-11-03 22:40:31

SQL Server的高级知识的相关文章

SQL Server内存方面知识收集

浅谈SQL Server 对于内存的管理 http://www.cnblogs.com/CareySon/archive/2012/08/16/HowSQLServerManageMemory.html SQL Server内存方面知识收集

SQL Server T-SQL高级查询(转)

高级查询在数据库中用得是最频繁的,也是应用最广泛的.   ? 基本常用查询   --select select * from student; --all 查询所有 select all sex from student; --distinct 过滤重复 select distinct sex from student; --count 统计 select count(*) from student; select count(sex) from student; select count(di

SQL server 数据库基本知识

一.数据库三个层次: 库文件.服务.管理界面 二.关于数据库的小知识: DB:指数据库存储数据的文件DBMS:数据库管理系统DBS:数据库系统,包含人,机器硬件,DB和管理程序MDF:主数据文件NDF:次数据文件IDF:日志文件 三.SA账号的启用 Windows验证登录 服务上属性 安全性 选择验证方式 启用sa并设置密码 重启服务重启后,以后尽量用sa连接 四.备份 右键要备份的数据库名称————任务————备份 五.分离 右键要分离的数据库名称————任务————分离 六.还原 新建一个数

SQL Server T-SQL高级查询

name like 'ja%'; select * from student where name not like '%[j,n]%'; select * from student where name like '%[j,n,a]%'; select * from student where name like '%[^ja,as,on]%'; select * from student where name like '%[ja_on]%'; --in 子查询 select * from

sql server 2008 基础知识

一.配置管理器 1.管理服务 使用配置管理器可以启动.停止.重新启动.继续或暂停服务. 服务器和客户端网络协议 2.SQLSMS 简介:SQLSMS是一个集成环境,用于访问.配置.管理和开发SQL Server的所有组件. 注册服务器:为客户机确定一台SQL Server数据库所在的机器,及服务器. 4.Sqlcmd工具 sqlcmd通过OLE DB与服务器进行通信,使用sqlcmd工具可以在命令提示符窗口中输入T-SQL语句,调用系统过程和脚本文件. T-SQL脚本文件是一个文本文件,可以包含

sql server 游标的知识

一:认识游标   游标是SQL Server的一种数据访问机制,它允许用户访问单独的数据行.用户可以对每一行进行单独的处理,从而降低系统开销和潜在的阻隔情况,用户也可以使用这些数据生成的SQL代码并立即执行或输出. 1.游标的概念  游标是一种处理数据的方法,主要用于存储过程,触发器和 T_SQL脚本中,它们使结果集的内容可用于其它T_SQL语句.在查看或处理结果集中向前或向后浏览数据的功能.类似与C语言中的指针,它可以指向结果集中的任意位置,当要对结果集进行逐条单独处理时,必须声明一个指向该结

SQL Server 常用高级语法笔记

1.case...end (具体的值)case后面有值,相当于c#中的switch case注意:case后必须有条件,并且when后面必须是值不能为条件. -----------------case--end---语法结构--------------------- select name , --注意逗号 case level --case后跟条件 when 1 then '骨灰' when 2 then '大虾' when 3 then'菜鸟' end as'头衔' from [user]

SQL server 的基础知识的学习(1)

1.DISTINCT distinct这个关键字用来过滤掉多余的重复记录只保留一条,但往往只用它来返回不重复记录的条数,而不是用它来返回不重记录的所有值.其原因是distinct只有用      二重循环查询来解决,而这样对于一个数据量非常大的站来说,无疑是会直接影响到效率的. 2.ORDER BY ORDER BY 语句用于根据指定的列对结果集进行排序. ORDER BY 语句默认按照升序(Ascending)对记录进行排序.降序(Descending) select(列1,列2,...)fr

第五篇 SQL Server代理理解代理错误日志

本篇文章是SQL Server代理系列的第五篇,详细内容请参考原文. 正如这一系列的前几篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行.在第四篇中我们看到,SQL Server代理可以通过数据库邮件发送通知.如果有什么不正确的,你必须查看数据库邮件日志.在这一篇,你将学习如何理解和查看所有相关的SQL Server代理错误日志.你将回顾最常见的错误信息,掌握哪些信息需要你采取行动,哪些信息只是单纯的信息而已.一旦你理解错误日志,在处理SQL Serv