QL Server 实用脚本

Posted justqi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QL Server 实用脚本相关的知识,希望对你有一定的参考价值。

use MyFirstDB;

-- 主要内容
-- SQL Server 实用脚本
-- 1、case语句
-- 2、子查询
-- 3、连接查询
-- 4、脚本变量与流程控制(选择与循环等)
-- 5、事务
-- 6、存储过程
-- 7、触发器

---------------------------------
-- case 语句
-- 类似于C#中的三元表达式,好比n元表达式
-- 语法
-- 1)写在哪里? 在sql语句中需要值(标量)的地方
-- 2)
-- if-else结构
/*
case
when 条件then 值
when 条件then 值
...
else 默认值
end
*/
select
stuName
, case
when stuSex=m then 
when stuSex=f then 
    else 其他
end as 性别
, datediff(YEAR, stuBirthdate, GETDATE()) as 年龄
--,*
from
TestDataBase..Student
where
stuId<20;
--
-- switch-case结构
/*
case 字段
when 值then 结果
when 值 then 结果
...
else 默认值
end
*/
select
DATEDIFF(YEAR, stuBirthdate, GETDATE()) as 年龄
,case stuSex
when m then 
when f then 
    else 其他
end as 性别
, *

from
TestDataBase..Student
where
stuId<20;
-- 练习
create table test
(
number varchar(10),
amount int
)
insert into test(number,amount) values(RK1,10)
insert into test(number,amount) values(RK2,20)
insert into test(number,amount) values(RK3,-30)
insert into test(number,amount) values(RK4,-10)

--
select * from test;

select number, 收入, 支出 from test;

select
number
, case when amount>=0 then amount else 0 end as 收入
, case when amount<0 then abs(amount) else 0 end as 支出
from Test
-------------------------------------
create table Score
(
学号 nvarchar(10),
课程 nvarchar(10),
成绩 int
)

insert into Score values(0001,语文,87);
insert into Score values(0001,数学,79);
insert into Score values(0001,英语,95);
insert into Score values(0002,语文,69);
insert into Score values(0002,数学,84);
--
select * from Score;
-- 表的透视变换ANSI-SQL的做法
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
学号
-- T-SQL2008 透视变换与你透视变换PIvote UnPivote
----------------------------

-- 2、子查询
-- 什么是子查询?
-- 在一个查询中,一个查询的结果作为另一个查询的条件,那么这个
--  查询称为子查询,这个使用条件的查询称为外部查询
-- 查询“纪明杰”的考试成绩
select stuId from TestDataBase..Student where stuName=纪明杰;
select * from TestDataBase..Score where stuId=1;

select * from TestDataBase..Score where stuId =
(select top 1 stuId from TestDataBase..Student where stuName=纪明杰);

-- 查询“濮阳语儿”
-- select * from TestDataBase..Student order by stuId;
select * from TestDataBase..Score where stuId in
(select stuId from TestDataBase..Student where stuName=濮阳语儿);

-- 标量子查询与多值子查询
-- 独立子查询

-- 相关子查询
-- 查询"纪明杰"的考试平均分(三个科目的综合求avg)
select
stuName
, (
select avg(testBase+testBeyond+testPro)
from TestDataBase..Score
where stuId = t.stuId -- 此时子查询需要使用外部查询的stuId
)分数 -- 只需要放至id号位纪明杰同学的分数即可
from
TestDataBase..Student as t
where
stuName=濮阳语儿;

-- 3、连接查询(表连接)
-- 为什么要使用这个,这个是什么
-- 就是将多张表合并成一张表
-- 查询"纪明杰"的信息
-- 个人信息(Student)、分数信息(Score)、课程信息(Course)
select
t1.*
, t2.className, t2.classDescription
, t3.testBase,t3.testBeyond,t3.testPro
from
TestDataBase..Student as t1
inner join
TestDataBase..Course as t2
on t1.classId = t2.classId
inner Join
(select
stuId
, avg(testBase) as TestBase
, AVG(testBeyond) as testBeyond
, avg(testPro) as testPro
from
TestDataBase..Score
group by
stuId) as t3
on t1.stuId = t3.stuId
where
t1.stuName = 纪明杰;

-- 连接操作的分类:交叉连接、内链接、外连接(左外、右外、全连接)

--
select * into TestDataBase..Employee from
(values (1, 马伦, 2),
(2, 赵晓虎, 1),
(3, 杨中科, null)
) as Employee(empId, empName, titleId);

select * into TestDataBase..Title from
(values
(1, 讲师)
, (2, 学科负责人)
) as title(titleId, titleName);

select * from TestDataBase..Employee;
select * from TestDataBase..Title;

select * from
TestDataBase..Employee
cross join
TestDataBase..Title;

select * from

(select * from
(values (1, 马伦, 2),
(2, 赵晓虎, 1),
(3, 杨中科, null)
) as Employee(empId, empName, titleId)) as t1
cross join
(select * from
(values
(1, 讲师)
, (2, 学科负责人)
) as title(titleId, titleName)) as t2;

------------------------------
-- numTbl(num)  1-10000
create table numTbl
(
num int not null
);
insert into numTbl(num) values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9);

select * from numTbl;

select
t1.num + t2.num * 10 + t3.num*100 + t4.num * 1000 + t5.num*10000 + 1 as n
from
numTbl as t1
cross join
numTbl as t2
cross join
numTbl as t3
cross join
numTbl as t4
cross join
numTbl as t5
order by
n

select * from sys.objects;

-- 内链接的实现
use TestDataBase;
select stuId, stuName from Student;
select * from Course;

select t1.stuId, t1.stuName, t2.className from
Student as t1
inner join
Course as t2
on t1.classId = t2.classId
order by
t1.stuId;

-- 语法注意
-- ANSI-SQL 89
select * from Employee, Title;
select * from Employee t1, Title t2 where t1.titleId=t2.titleId;
-- ANSI-SQL 92

-- 外连接
select * from
Employee as t1
full join
Title as t2
on t1.titleId = t2.titleId;

-- 4、表表达式
-- 派生表、公用表表达式(CTE)、视图(、内联表值函数)
-- 派生表就是由一个查询得到的结果集,作为数据源被查询,这个结果集就是派生表
/*
select
*
from -- 学生的完整信息
(select * from ...) as t
where
t.stuName=‘濮阳语儿‘;
*/
-- 使用派生表实现分页
select * from TestDataBase..Student order by stuId;
-- 第一页,每页十条
select top 10 * from Student order by stuId;
-- 第二页,每页十条(11-20)
-- 第三页(21-30)
select top 10
*
from
Student
where
stuId not in(
select top ((@pageIndex-1) * @pageCount) stuId from Student order by stuId
)
order by
stuId;
-- between and
select * from Student where stuId between 1 and 10;
select * from Student where stuId between 11 and 20;
select * from Student where stuId between 21 and 30;
select * from Student where stuId between (@pageIndex - 1) * @pageCount + 1 and @pageIndex * @pageCount;

-- 显示第n也,每页显示m条记录

select * from
( -- 派生表
select
ROW_NUMBER() over(order by stuId) as num
, *
from
Student
) as t
where
t.num between (n-1)*m + 1 and n * m;

-- 公用表表达式(CTE common table expression)
-- 为什么要有这个东西
--with 别名
--as
--(
-- 结果集
--)
--查询

with t
as
(
select
ROW_NUMBER() over(order by stuId) as num
, stuName
, stuSex
, stuBirthdate
, stuStudydate
, stuAddress
, stuEmail
, stuPhone
, stuIsDel
, stuInputtime
, classId
from
Student
where
stuIsDel = 0
)
select
t.num as 编号
, t.stuName as 姓名
, datediff(year, t.stuBirthdate, getdate()) as 年龄
, convert(varchar, t.stuStudydate, 111) as 入学时间
, t.stuEmail as 电子邮件

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

-- 视图(view)
-- 为什么要使用视图
-- 视图的本质,是对系统中具体的物理表的复杂查询的一个映射,其本质还是一个查询
-- 可以认为是一个查询的别名
/*
create view 架构.vw_视图名
as
结果集
*/
go
create schema pub authorization dbo;
go
create view pub.vw_StuInfo
as
select
ROW_NUMBER() over(order by stuId) as num
, stuName
, stuSex
, stuBirthdate
, stuStudydate
, stuAddress
, stuEmail
, stuPhone
, stuIsDel
, stuInputtime
, className
, classDescription
from
Student as t1
inner join
Course as t2
on t1.classId = t2.classId
where
t1.stuIsDel = 0
;
go

select * from vw_StuInfo where num between 11 and 20;

-- 在使用非常复杂的sql语句查询数据的时候
-- 将查询进行打包(记录的sql语句,是结果集),取了一个名字
-- 在查询的时候就不需要使用非常复杂的sql语句了
-- 直接使用这个结果集

select * from pub.vw_StuInfo;

-- 5、脚本变量与流程控制(选择与循环等)
-- 变量的使用(先声明,在赋值,后使用)
declare @varible varchar(10); -- 声明变量
-- set @varible = ‘测试数据‘; -- 赋值
-- set @varible = (select ‘测试的数据‘); -- 标量子查询赋值
select @varible=stuName from Student where stuId = 3;

select @varible; -- 使用变量

-- 选择结构
if ()
begin
语句
end
else if ()
begin
end
else
begin
end

-- 循环结构
while(表达式)
begin
end

-- 求到中所有偶数的和
declare @sum int;
declare @i int;
select @sum=0, @i=0;
while @i <= 100
begin
if (@i % 2 = 0)
begin
set @sum = @sum + @i;
end
set @i = @i + 1;
end
select @sum;

-- 6、事务
--事务
create table bank
(
cId char(4) primary key,
balance money --余额
)

alter table bank
add constraint CH_balance check(balance >=10)

go
--delete from bank
insert into bank values(0001,1000)
insert into bank values(0002,10)
go

select * from bank;

update bank set balance=balance - 1000 where cid=0001
update bank set balance=balance + 1000 where cid=0002

-- 如何使用事务?
-- 在SQL Server中每一条sql语句默认为一个事务
insert into Employee(empId, empName, titleId) values
(4, 赵晓雪, null),
(5, 赵晓飞雪, null),
(6, 赵大雪, null)
-- 原子性

-- 手动使用事务
begin transaction
写代码
-- 提交事务,让这里的代码全部生效
commit transaction
-- 回滚事务,这里所有的操作无效
rollback transaction

begin transaction

delete from Score where Score.testId > 1;
delete from Student where stuId > 1;
delete from Course where classId > 1;

rollback transaction

select * from Student;
select * from Course;
select * from Score;

---------------------
-- @变量名 自定义变量
-- @@系统变量
@@error -- 记录最近一次sql语句执行的状态码,如果大于表示这条有错误

select @@ERROR;

begin transaction
declare @myError int;
set @myError = 0;
update bank set balance=balance - 500 where cid=0001
set @myError = @myError + @@ERROR;
update bank set balance=balance + 500 where cid=0002
set @myError = @myError + @@ERROR;
if @myError > 0
begin
rollback transaction
end
else
begin
commit transaction
end

select * from bank;

begin transaction
begin try
update bank set balance=balance + 600 where cid=0001
update bank set balance=balance - 600 where cid=0002
commit transaction
end try
begin catch
rollback transaction
end catch

-- 事务的特征:原子性、持久性、隔离性、一致性
-- 隔离级别、快照、锁定排查

-- 7、存储过程
-- 为什么需要存储过程?
-- 如何使用?(存储过程好比C#中的方法)
use master;
exec sp_detach_db mfb;

CREATE DATABASE Archive
      ON (FILENAME = d:\db\hei14\MyFirstDB.mdf)
      FOR ATTACH ;
GO
exec sp_renamedb MyFirstDB, mfb

-- 存储过程语法  usp_
--create procedure 存储过程的名字
--@变量类型[= 默认值] [output]
--,@变量类型[= 默认值] [output]
--,@变量类型[= 默认值] [output]
--as
--begin
-- 。。。
--end

-- 转账,每次转元
go
use TestDataBase;
go
create proc usp_转账
as
begin
begin transaction
begin try
update bank set balance=balance - 100 where cid=0001
update bank set balance=balance + 100 where cid=0002
commit transaction
end try
begin catch
rollback transaction
end catch
end;
go
exec usp_转账;
select * from bank;

go
create proc usp_转账
@from char(4)
, @to char(4)
, @money money
as
begin
begin transaction
begin try
update bank set balance=balance - @money where cid=@from
update bank set balance=balance + @money where cid=@to
commit transaction
end try
begin catch
rollback transaction
end catch
end;
go
-- 调用带有参数的存储过程
exec usp_转账 0001, 0002, 200.00

exec usp_转账 @to=0001, @from=0002, @money=1000

select * from bank;

go
create proc usp_转账
@from char(4)
, @to char(4)
, @money money
, @isSuccess int output
as
begin
begin transaction
begin try
update bank set balance=balance - @money where cid=@from
update bank set balance=balance + @money where cid=@to
commit transaction
set @isSuccess = 1;
end try
begin catch
rollback transaction
set @isSuccess = 0;
end catch
end;
go

-- 需要一个变量
declare @res int
-- exec usp_转账‘0001‘, ‘0002‘, 500, @res output;
exec usp_转账 @isSuccess=@res output, @to=0001, @from=0002, @money=500

select @res;

select * from bank;

-- 使用C#执行存储过程的步骤:
-- 1、将sql语句变成存储过程的名字
-- 2、将SqlCommand对象的CommandType设置为StoredProcedure

exec sp_help;

-- 8、触发器
-- 什么是?
-- 是存储过程,类似于c#中的事件
-- 什么时候使用?
-- 跨数据库表等对象所做的验证
-- 监视数据变动
-- 语法?
-- 触发器的分类:after触发器、instead of触发器
-- 针对增删改操作进行触法

-- 语法
/*
create trigger tr_触发器名字on 表名
after | instead of
update | delete | insert
as
begin
代码
end
*/

-- inserted表deleted表
-- 是在增加数据、删除数据或修改数据的过程中临时创建的表

-- 如何得到刚刚插入数据的id号

select * from Employee;
insert into Employee(empName) values(赵晓虎);

insert into Employee(empName) output inserted.* values(赵晓);

go
create trigger tr_永远删除不了的数据 on Employee
after
delete
as
-- 将删除的数据插入回来
insert into Employee(empName, titleId)
select empName, titleId from deleted;
go

delete from Employee;

truncate table Employee;

select SUSER_SNAME();

go
create trigger tr_watch_insert on Employee
after
insert
as
begin
declare @res varchar(500);
set @res = 用户‘‘‘ + suser_name() + ‘‘‘添加数据:;
set @res = @res + (select empName from inserted);
print @res;
end

select * from Employee;

insert into Employee(empName) values(wcw);

-- 什么是?
-- 干什么用?
-- 语法

 

以上是关于QL Server 实用脚本的主要内容,如果未能解决你的问题,请参考以下文章

30 段 Python 实用代码

即学即用的 30 段 Python 实用代码

Android 实用代码片段

Android 实用代码片段

asp.net页面实用代码片段

实用代码片段