首页 > 代码库 > 变量,存储过程,触发器,事务-索引等

变量,存储过程,触发器,事务-索引等

--SELECT TOP 3 Name,Age,Gender FROM View_Student WHERE GROUP having ORDER BY id DESC
----在最终生成用户想要的数据之后,才进行排序,如果不得不排序,那么就尽可能吧消耗减到最小

--ALTER VIEW View_Student
--AS 
--SELECT * FROM dbo.Student

DECLARE @num INT
--赋值,取值 
--赋值两种方式:set select
SET @num=100
SELECT @num=200

--取值
--打印出 一个 值
--PRINT @num

--SELECT @num=MAX(Age) FROM dbo.Student
--PRINT @num

--SELECT @num = COUNT(id) FROM dbo.Student
--PRINT @num

SELECT @num=Age FROM dbo.Student
PRINT @num
--变量的默认值是null(不知道)
--DECLARE @tid INT
--SET @tid=@tid+1
--PRINT @tid


DECLARE @tid INT
SET @tid=2
SELECT * FROM dbo.Student WHERE id =@tid

--给变量设置初始值
DECLARE @ida INT = 3
SELECT * FROM dbo.Student WHERE id =@ida

DECLARE @tnum INT =5
SELECT @tnum,2,3

--当前连接的局部变量
PRINT @tnum

PRINT @@version
--语法错误
--SET @@version=‘aaaaa‘

--SELECT naa FROM dbo.Student--207
--要创造两个不是语法错误的错误

INSERT INTO dbo.Classes VALUES (a)--213
SELECT * FROM dbo.Student WHERE id=a--245


--系统变量
--error 记录的是最后一个出现错误的地方的错误号(消息后面的数字)
--事务,必须用到
PRINT @@ERROR


INSERT INTO dbo.Classes VALUES(大班,上一个学期是中班)
PRINT @@IDENTITY --null

PRINT @@LANGUAGE

--每台服务器可以同时创建的connection数量是有限的
PRINT @@MAX_CONNECTIONS

--上一次语句的受影响行数
UPDATE dbo.Student SET Age =Age +1 WHERE id=3
PRINT @@ROWCOUNT

PRINT @@SERVERNAME

PRINT @@TRANCOUNT

SELECT * FROM dbo.Student WHERE id =(SELECT id  FROM dbo.Classes WHERE id=1)

SELECT Age FROM dbo.Student
DECLARE @numa INT = 1
--在赋值的同时,不能取值
SELECT @numa=Age+1 FROM dbo.Student
PRINT @numa


IF( (SELECT COUNT(id) FROM dbo.Student) >10)
BEGIN
PRINT 好多人啊
PRINT 今天天气不错
END
ELSE
BEGIN
PRINT 人好少啊
END


--计算english平均分数并输出,如果平均分数超过60分输出成绩最高的三个学生的成绩,否则输出后三名的学生
DECLARE @avgenglish INT
SELECT @avgenglish=AVG(English) FROM dbo.Score
IF(@avgenglish>60)
BEGIN
SELECT TOP 3 * FROM dbo.Score ORDER BY English DESC 
END
ELSE
begin
SELECT TOP 3 * FROM dbo.Score ORDER BY English ASC
END

--计算1-100之间所有奇数的和。

--循环 1-100 
--判断是否为奇数(数字余2是1)
--是 就加起来

DECLARE @numc INT = 1
DECLARE @sumnum INT =0
WHILE(@numc<=100)
begin
IF(@numc%2 =1)
BEGIN
SET @sumnum=@sumnum+@numc
END
SET @numc=@numc+1
END
PRINT @sumnum

DECLARE @numd INT =1
WHILE(1=2)
BEGIN
PRINT 今天天气不好
END


--如果english不及格的人超过半数(考试题出难了),则给每个人增加2分,循环加,直到不及格的人数少于一半。
--1.取出不及格的人数,
--2.取出总人数
--3.判断不及格人数是否大于总人数/2
--4.开始循环,给学员加分

--解法一
--DECLARE @nume INT=0--不及格的人数
--SELECT @nume=COUNT(id) FROM dbo.Score WHERE English<60
--DECLARE @allnum INT =0--总人数
--SELECT @allnum=COUNT(id)/2 FROM dbo.Score
--WHILE(@nume>@allnum)
--begin
----加分
--UPDATE dbo.Score SET English=English+2
--SELECT @nume=COUNT(id) FROM dbo.Score WHERE English<60
--END
--UPDATE dbo.Score SET English =100 WHERE english>100



--解法二
--DECLARE @nume INT=0--不及格的人数
--SELECT @nume=COUNT(id) FROM dbo.Score WHERE English<60

DECLARE @allnum INT =0--总人数
SELECT @allnum=COUNT(id)/2 FROM dbo.Score
WHILE((SELECT COUNT(id) FROM dbo.Score WHERE English<60)>@allnum)
begin
--加分
UPDATE dbo.Score SET English=English+2
--SELECT @nume=COUNT(id) FROM dbo.Score WHERE English<60
END
UPDATE dbo.Score SET English =100 WHERE english>100

 


存储过程

--传入一个金额,自动的从0001转到0002,写成存储过程

CREATE PROC usp_ZZ
@mon INT =0
AS
BEGIN
DECLARE @sumerr INT =0---默认值必须加
BEGIN TRANSACTION

UPDATE dbo.bank SET balance =balance-@mon WHERE cId=0001
SET @sumerr=@sumerr+@@ERROR
UPDATE dbo.bank SET balance =balance+@mon WHERE cId=0002
SET @sumerr=@sumerr+@@ERROR

IF(@sumerr >0)
BEGIN
ROLLBACK TRANSACTION
END
ELSE
BEGIN
COMMIT TRANSACTION
END
END


EXEC usp_ZZ 1000

 

 

----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

--转账问题
--1.从A账户扣除1000--DECLARE @zhuan INT =0
--SET @zhuan=99999999
--UPDATE dbo.bank SET balance=balance-@zhuan WHERE cId=‘0001‘
----2.从B账户增加1000
--UPDATE dbo.bank SET balance=balance+@zhuan WHERE cId=‘0002‘


DECLARE @zhuan INT
SET @zhuan=99999999
DECLARE @sumerr INT = 0

--每一条语句执行之后,系统都会更新@@Error变量的值,如果出现 错误就是错误号,如果没有错误就是0
--系统在一个事务里面不会自动累加错误号,因为错误号都是有意义的,不能随便乱赋值
--所以,我们需要手动累加错误号,才能知道到底是否出现了错误
BEGIN TRANSACTION--开始事务(告诉数据库,事务启动,准备好啦)
--增,删,改
UPDATE dbo.bank SET balance=balance-@zhuan WHERE cId=0001
SET @sumerr=@sumerr+@@Error--0
UPDATE dbo.bank SET balance=balance+@zhuan WHERE cId=0002
SET @sumerr=@sumerr+@@Error--547

IF(@sumerr <= 0)
BEGIN
COMMIT TRANSACTION--提交事务,提交修改,保存修改,确认修改--成功
END
ELSE
BEGIN
ROLLBACK TRANSACTION--回滚事务,放弃事务,放弃操作--失败
END


BEGIN TRANSACTION
INSERT INTO dbo.Classes VALUES(aaa,bbb)--547
@@error
INSERT INTO dbo.Classes VALUES(aaa,bbb)
INSERT INTO dbo.Classes VALUES(aaa,bbb)
INSERT INTO dbo.Classes VALUES(aaa,bbb)
INSERT INTO dbo.Classes VALUES(aaa,bbb)

COMMIT TRANSACTION


DECLARE @@aaa INT=100--null
PRINT @@aaa

PRINT @@Error

DECLARE @lastage INT=0
SELECT @lastage=100 FROM dbo.Student  WHERE 1<>1
select @lastage


--**************************存储过程
--由存储过程名/存储过程参数组成/可以有返回结果。--存储过程
--由    方法名/    方法参数组成/可以有返回结果 的方法。--C#方法

--存储过程:存储在数据库里面的 处理数据的过程(一堆sql语句)

--CREATE--创建,ALTER--修改

--创建或修改存储过程
ALTER PROC usp_GetStu
AS
begin
SELECT * FROM dbo.Student
END

--调用存储过程,就相当于在C#调用了一个没有参数,没有返回值的方法
EXEC GetStu

EXEC sp_databases
EXEC sp_helpdb

EXEC sp_tables NULL,dbo
EXEC sp_columns Area

EXEC sp_help

EXEC sp_helpconstraint Area

EXEC sp_helpindex Area

EXEC sp_helptext GetStu

DECLARE @nums INT = 0

ALTER PROC usp_GetStu
@iid INT = 2,--有默认值的参数可以不传
@name nvarchar(10) --对于没有写默认值的参数,在调用的时候必须传递参数,
--在存储过程的参数被定义的时候,可以指定默认值
AS
begin
SELECT * FROM dbo.Student WHERE Name=@name
SELECT * FROM dbo.Student WHERE id=@iid
END

--调用一个带参数的存储过程,参数在存储过程名字后面加上一个空格之后
EXEC usp_GetStu 2,啊三--调用一个带有两个参数的存储过程

EXEC usp_GetStu @name=啊三--调用一个带两个参数的存储过程,但是只传递后面一个参数的值

EXEC usp_GetStu @iid=2,@name=jake--调用一个带两个参数的存储过程,传两个参数
EXEC usp_GetStu @name=jake,@iid=2--

EXEC usp_GetStu @iid=2



ALTER PROC usp_GetStu
@iid INT = 2,--有默认值的参数可以不传
@name nvarchar(10), --对于没有写默认值的参数,在调用的时候必须传递参数,
--在存储过程的参数被定义的时候,可以指定默认值
@totalCount int =0 OUTPUT--定义一个输出参数
AS
begin
SELECT * FROM dbo.Student WHERE Name=@name
SELECT * FROM dbo.Student WHERE id=@iid
SELECT @totalCount=COUNT(id) FROM dbo.Student
END

DECLARE @total INT =0
EXEC usp_GetStu @name=啊三,@totalCount=@total OUTPUT--指定一个变量给输出参数,
--在存储过程执行完毕以后,我们就可以通过变量得到数据的值了
EXEC usp_GetStu 2,阿三,@total OUTPUT
SELECT @total

--考试题出难了,降低及格分数线60,(将该题目封装为一个存储过程。
--条件:及格人数 小于 总人数一半
--结果:输出最后的分数线

--100分及格 看看有多少人没有及格的,如果及格人数 小于 总人数一半 就降低5分
--95      。。。。
--90
--直到及格人数 大于 总人数一半  输出及格线分数

--作业:编写存储过程usp_upGrade
--要求传入及格分数参数:@pass float
--给没及格的人提分,一直加到及格人数大于总人数一半

--结果:输出调整之后的学员姓名及分数(select)


--有一个年龄,查找出所有年龄大于这个数字的人的信息,然后要有总人数
ALTER PROC usp_GetStu 
@age int = 25,
@outCount int OUTPUT
AS
begin
SELECT @outCount= COUNT(id) FROM dbo.Student WHERE Age >@age
SELECT * FROM dbo.Student WHERE Age >@age
END

DECLARE @otc int
EXEC usp_GetStu 25,@otc OUTPUT
SELECT @otc

--*******************分页存储过程

CREATE PROC usp_GetAreaPage
@pageIndex INT = 3,--当前页码
@pageSize INT =10 --页容量
AS
begin
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY ar_id) AS rownum,* FROM Area) AS t
WHERE t.rownum BETWEEN @pageSize*(@pageIndex-1)+1 AND @pageSize*@pageIndex
END


EXEC usp_GetAreaPage 2,5


--***********************触发器
--新增,修改,删除,查询没有触发器

--创建一个新增触发器
CREATE TRIGGER tgforClassesOnInsert ON Classes
AFTER INSERT 
as
begin
PRINT 新增了一行数据
--INSERT INTO log (操作的表,执行时间,哪个用户)
END
--创建一个删除触发器
CREATE TRIGGER tgforClassesOnDelete ON Classes
AFTER DELETE
as
begin
PRINT 删除了一行数据
END
--创建一个修改触发器
CREATE TRIGGER tgForClassesOnUpdate ON Classes
AFTER UPDATE
as
begin
PRINT 修改了一行数据
END

--*********FOR
CREATE TRIGGER tgclassupdate ON classes
FOR    update
as
begin
PRINT for的更新
END
CREATE TRIGGER tgclassinsert ON classes
FOR    INSERT
as
begin
PRINT for的插入
END
CREATE TRIGGER tgclassdelete ON classes
FOR    DELETE
as
begin
PRINT for的删除
END
--************instead OF
CREATE TRIGGER tgclassesIinsert ON classes
instead OF INSERT
as
begin
PRINT instead ++ INSERT
END
CREATE TRIGGER tgclassesIupdate ON classes
instead OF update
as
begin
PRINT instead ++ update
END
CREATE TRIGGER tgclassesIdelete ON classes
instead OF delete
as
begin
PRINT instead ++ delete
END


--根据业务需求,在增删改之后我们需要做什么
INSERT INTO dbo.Classes
        ( Name, Descr )
VALUES  ( N十七班, -- Name - nvarchar(16)
          N1700  -- Descr - nvarchar(128)
          )

UPDATE dbo.Classes SET Name=十八班 WHERE id =21

DELETE FROM dbo.Classes WHERE id=33