局部变量_先声明再赋值

声明局部变量

DECLARE @变量名 数据类型

DECLARE @name varchar(20)

DECLARE @id int

赋值

SET @变量名 =值

--set用于普通的赋值

SELECT @变量名 = 值

--用于从表中查询数据并赋值,,可以一次给多个变量赋值

例如:

SET @name=‘张三’

SET @id = 1

SELECT @name = sName FROM student WHERE sId=@id

输出变量的值

SELECT 以表格的方式输出,可以同时输出多个变量

PRINT 以文本的方式输出,一次只能输出一个变量的值

SELECT @name,@id

PRINT @name

PRINT @id

变量种类

变量分为:

局部变量:

局部变量必须以标记@作为前缀 ,如@Age int

局部变量:先声明,再赋值

全局变量(系统变量):

全局变量必须以标记@@作为前缀,如@@version

全局变量由系统定义和维护,我们只能读取,不能修改全局变量的值

讲解要点:
和C语言中的变量进行类比,让学员容易接受。
强调:
1.局部变量标志:一个◎;全局变量标志:两个◎
2. 我们可以定义局部变量,但不能定义全局系统变量,但我们能读取全局系统变量的值。
如当前是否执行有错误:@@ERROR
变量 含义
@@ERROR 最后一个T_SQL错误的错误号
@@IDENTITY 最后一次插入的标识符
@@LANGUAGE 当前使用的语言的名称
@@MAX_CONNECTIONS 可以创建的同时连接的最大数目
@@ROWCOUNT 受上一个SQL语句影响的行数
@@SERVERNAME 本地服务器的名称
@@TRANSCOUNT 当前连接打开的事务数
@@VERSION SQL Server的版本信息

print 'SQLServer的版本'+@@VERSION

print '服务器名称: '+@@SERVERNAME

print ‘最后一次放生的错误号'+convert(varchar(5),@@ERROR)

print @@identity

IF ELSE

IF(条件表达式)

BEGIN --相当于C#里的{

语句1

……

END--相当于C#里的}

ELSE

BEGIN

语句1

……

END

计算平均分数并输出,如果平均分数超过60分输出成绩最高的三个学生的成绩,否则输出后三名的学生
declare @avg float
select @avg = avg(english) from score
print '平均分数' + convert(varchar(20),@avg)
if(@avg > 60)
Begin
print '前三名‘
select top 3 sName,english from student inner join score on student.sId=score.studentId order by english desc
End
Else
begin
print '后三名'
select top 3 sName,english from student inner join score on student.sId=score.studentId order by english asc
end
declare @avg float
select @avg = avg(english) from score
print '平均分数' + convert(varchar(20),@avg)
if(@avg > 60)
begin
print '前三名'
select top 3 sName,english from student inner join score on student.sId=score.studentId order by english desc
end
else
begin
print '后三名'
select top 3 sName,english from student inner join score on student.sId=score.studentId order by english asc
end

WHILE循环

WHILE(条件表达式)
BEGIN --相当于C#里的{
语句
……
BREAK
END --相当于C#里的}

如果不及格的人超过半数(考试题出难了),则给每个人增加2分

把所有未及格的人的成绩都加及格

--delete from Score
insert into Score (studentId,english) values(1,50)
insert into Score (studentId,english) values(2,40)
insert into Score (studentId,english) values(3,59)
insert into Score (studentId,english) values(4,20)
insert into Score (studentId,english) values(5,90)
insert into Score (studentId,english) values(6,20)
insert into Score (studentId,english) values(7,10)
--如果不及格的人超过半数(考试题出难了),则给每个人增加分
declare @count int --参加考试总人数
declare @failCount int --不及格人数
select @count = count(*) from score
select @failCount = count(*) from score where english < 60 while @failCount > @count/2
begin
update score set english = english + 2
select @failCount = count(*) from score where english < 60
end
update score set english = 100 where english > 100
select * from score
--把所有未及格的人的成绩都加及格
declare @count int
while(1=1)
begin
select @count = count(*) from score where english < 60
if(@count > 0)
begin
update score set english = english + 2
end
else
break
end
update score set english = 100 where english > 100
select * from score

事务-为什么需要事务

如,转账问题:

假定钱从A转到B,至少需要两步:

A的资金减少

然后B的资金相应增加

update bank set balance=balance-1000 where cid=''
update bank set balance=balance + 1000 where cid=''

-查看结果。 SELECT * FROM bank

-事务
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('',1000)
insert into bank values('',10)
go
update bank set balance=balance-1000 where cid=''
update bank set balance=balance + 1000 where cid=''

什么是事务(Transaction)

事务:同生共死

指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)--也就是由多个sql语句组成,必须作为一个整体执行

这些sql语句作为一个整体一起向系统提交,要么都执行、要么都不执行

语法步骤:

开始事务:BEGIN TRANSACTION

事务提交:COMMIT TRANSACTION

事务回滚:ROLLBACK TRANSACTION

判断某条语句执行是否出错:

全局变量@@ERROR;

@@ERROR只能判断当前一条T-SQL语句执行是否有错,为了判断事务中所有T-SQL语句是否有错,我们需要对错误进行累计;

例:SET @errorSum=@errorSum+@@error

select * from bank

--使用事务
begin transaction
declare @error int
set @error = 0
update bank set balance=balance-1000 where cid=''
set @error = @error + @@error
update bank set balance=balance + 1000 where cid=''
set @error = @error + @@error
if @error != 0
rollback transaction
else
commit transaction
go
select * from bank

存储过程

存储过程---就像数据库中运行方法(函数)

和C#里的方法一样,由存储过程名/存储过程参数组成/可以有返回结果。

前面学的if else/while/变量/insert/select 等,都可以在存储过程中使用

优点:

执行速度更快 – 在数据库中保存的存储过程语句都是编译过的

允许模块化程序设计 – 类似方法的复用

提高系统安全性 – 防止SQL注入

减少网络流通量 – 只要传输 存储过程的名称

系统存储过程

由系统定义,存放在master数据库中 名称以“sp_”开头或”xp_”开头

自定义存储过程

由用户在自己的数据库中创建的存储过程

系统存储过程

系统存储过程 说明
sp_databases 列出服务器上的所有数据库
sp_helpdb 报告有关指定数据库或所有数据库的信息
 sp_renamedb 更改数据库的名称 
 sp_tables 返回当前环境下可查询的对象的列表 
 sp_columns 回某个表列的信息 
 sp_help 查看某个表的所有的信息 
 sp_helpconstraint 查看某个表的约束 
 sp_helpindex 查看某个表的索引 
 sp_stored_procedures 列出当前环境中的所有存储过程 
 sp_password 添加或修改登录账户的密码 
 sp_helptext 显示默认值、未加密的存储过程、用户定义的 存储过程、触发器或视图的时机文本

创建存储过程

定义存储过程的语法
CREATE PROC[EDURE] 存储过程名
@参数1 数据类型 = 默认值 OUTPUT,
@参数n 数据类型 = 默认值 OUTPUT
AS
SQL语句
参数说明:
参数可选
参数分为输入参数、输出参数
输入参数允许有默认值
EXEC 过程名 [参数]
--大部分学生不及格,提分,直到一半学生及格为止
if exists(select * from sysobjects where [name]='usp_upGrade')
drop proc usp_upGrade
go
create proc usp_upGrade
as
begin
declare @count int --记录总人数
set @count = (select count(*) from score)
while @count/2 < (select count(*) from score where english<60)
begin
update score set english= english+ 2
end
update score set english = 100 where english> 100
end
go

编写存储过程

考试题出难了,降低及格分数线

编写存储过程usp_upGrade

要求传入参数:@pass float

掉用存储过程,及格分数线,给没及格的人提分

-带输入参数的存储过程
--题出难了,降低及格分数线
if exists(select * from sysobjects where [name]='usp_upGrade1')
drop proc usp_upGrade1
go
create proc usp_upGrade1
@pass float = 60
as
begin
declare @count int --记录总人数
set @count = (select count(*) from score)
while @count/2 < (select count(*) from score where english<@pass)
begin
update gradeInfo set grade = grade + 2
end
update score set english = 100 where english> 100
end exec usp_upGrade1 80

调用带参数的存储过程

无参数的存储过程调用:

Exec usp_upGrade

有参数的存储过程两种调用法:

EXEC usp_upGrade2 60,55 ---按次序

EXEC usp_upGrade2 @english=55,@math=60 --参数名

参数有默认值时:

EXEC usp_upGrade2 --都用默认值

EXEC usp_upGrade2 1 --第一个用默认值

EXEC usp_upGrade2 1,5 --不用默认值

若想英语的用默认值,数学的及格分数改了怎么办?

存储过程中使用输出参数

如果希望在加分的过程中想输出总共加了多少次分

输出参数关键字:OUTPUT

实现登陆的存储过程

触发器

触发器是一种特殊类型的存储过程,它不同于前面介绍过的一般的存储过程。

一般的存储过程通过存储过程名称被直接调用,而触发器主要是通过事件进行触发而被执行。

触发器是一个功能强大的工具,在表中数据发生变化时自动强制执行。触发器可以用于SQL Server约束、默认值和规则的完整性检查,还可以完成难以用普通约束实现的复杂功能。

那究竟何为触发器?在SQL Server里面也就是对某一个表的一定的操作,触发某种条件,从而执行的一段程序。触发器是一个特殊的存储过程。 常见的触发器有三种:分别应用于Insert , Update , Delete 事件

常用语法

CREATE TRIGGER triggerName ON Table
for UPDATE|INSERT|DELETE
AS
begin

end

触发器-插入

CREATE TRIGGER tr_updateStudent ON score
for INSERT
AS
Begin
declare @sid int,@scoreid int
select @sid = studentId,@ scoreid=sid from inserted
if exists(select * from student where sid=@sid)
print ‘插入成功’
else
delete from score where sid = @scoreId
End
Insert into score (studentId,english) values(100,100)

触发器-删除

CREATE TRIGGER tr_deleteStudent ON student
for delete
AS
begin
insert into backupStudent select * from deleted
End Delete from student where sId=1

数据库的范式

表设计后,很可能结构不合理,出现数据重复保存,简称数据的冗余,这对数据的增删改查带来很多后患,所以我们需要审核是否合理,就想施工图设计后,还需要其他机构进行审核图纸是否设计合理一样。

如何审核呢?需要一些有关数据库设计的理论指导规则,这些规则业界简称数据库的范式。

对数据库审核  三大范式

第一范式的目标是确保每列的原子性 如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)

例如,如果关于员工的关系中有一个工资属性,而工资又由更基本的两个数据项基本工资和岗位工资组成,则这个员工的关系模式就不满足1NF。 员工表(员工号,姓名,工资)进行分解,使其满足1NF条件。

员工表(员工号,姓名,基本工资,岗位工资)

如果一个关系满足1NF,并且除了主键以外的其他列,都依赖与该主键,则满足第二范式(2NF) 第二范式要求每个表只描述一件事情

如果一个关系满足2NF,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式(3NF)

第三范式要求其它列必须直接依赖于主键

使用三大范式减少了数据冗余,但是牺牲了查询性能

所以有时为了性能,需要做适当折中,适当牺牲规范化的要求,来提高数据库的性能。

SQL面试题

1列出EMPLOYEES表中各部门的部门号,最高工资,最低工资

2列出EMPLOYEES表中各部门EMPLOYEE_JOB为'CLERK'的员工的最低工资,最高工资

3对于EMPLOYEES中最低工资小于1000的部门,列出EMPLOYEE_JOB为'CLERK'的员工的部门号,最低工资,最高工资

4根据部门号由高而低,工资有低而高列出每个员工的姓名,部门号,工资

5列出'张三'所在部门中每个员工的姓名与部门号

6列出每个员工的姓名,工作,部门号,部门名

7列出EMPLOYEES中工作为'CLERK'的员工的姓名,工作,部门号,部门名

数据库(class0507)的更多相关文章

  1. JSP应用开发 -------- 电纸书(未完待续)

    http://www.educity.cn/jiaocheng/j9415.html JSP程序员常用的技术   第1章 JSP及其相关技术导航 [本章专家知识导学] JSP是一种编程语言,也是一种动 ...

  2. nodejs进阶(6)—连接MySQL数据库

    1. 建库连库 连接MySQL数据库需要安装支持 npm install mysql 我们需要提前安装按mysql sever端 建一个数据库mydb1 mysql> CREATE DATABA ...

  3. GreenDao 数据库:使用Raw文件夹下的数据库文件以及数据库升级

    一.使用Raw文件夹下的数据库文件 在使用GreenDao框架时,数据库和数据表都是根据生成的框架代码来自动创建的,从生成的DaoMaster中的OpenHelper类可以看出: public sta ...

  4. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

    在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类 ...

  5. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  6. 在SQL2008查找某数据库中的列是否存在某个值

    在SQL2008查找某数据库中的列是否存在某个值 --SQL2008查找某数据库中的列是否存在某个值 create proc spFind_Column_In_DB ( @type int,--类型: ...

  7. 分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间)

    分享一个SQLSERVER脚本(计算数据库中各个表的数据量和每行记录所占用空间) 很多时候我们都需要计算数据库中各个表的数据量和每行记录所占用空间 这里共享一个脚本 CREATE TABLE #tab ...

  8. SQL Server2014 SP2新增的数据库克隆功能

    SQL Server2014 SP2新增的数据库克隆功能 创建测试库 --创建测试数据库 create database testtest use testtest go --创建表 )) --插入数 ...

  9. 数据库优化案例——————某市中心医院HIS系统

    记得在自己学习数据库知识的时候特别喜欢看案例,因为优化的手段是容易掌握的,但是整体的优化思想是很难学会的.这也是为什么自己特别喜欢看案例,今天也开始分享自己做的优化案例. 最近一直很忙,博客产出也少的 ...

随机推荐

  1. 手动安装UniDAC的过程

    每次安装都不一样,而且有时候挺麻烦的,所以记下来.我这次安装过程是这样的: 0. 修改Source\Delphi7\Make.bat,填入正确的IdeDir 1.找到source\delphi7目录, ...

  2. Android模拟器问题:No system images installed for this target

    CPU/ABI选项无法选择,提示:No system images installed for this target,也就是没有适合的系统镜像 打开Android Manager SDK 下载完后重 ...

  3. NSArray 初始化

    //NSArray长度不可变所以初始化的时候就赋值,并且最后以nil结尾 //此外需要注意NSArray不能存放C语言的基础类型 NSObject *obj=[[NSObject alloc]init ...

  4. Android给listview的item设定高度

    在item的layout文件中,用android:layout_height设置item的高度.运行,高度设置无效. 解决办法: 给item设定minHeight,即可. -------------- ...

  5. QTP公开课视频-持续更新中。。。

    以下是视频的下载地址: http://pan.baidu.com/share/link?shareid=1760499709&uk=3711405498

  6. SPOJ 1108 Card Trick 暴力模拟

    解释一下样例,因为我觉得这个题意表述的不是很清楚.以第二组样例为例. 牌序为:3 1 4 5 2 第一轮:把 3 放到末尾:1 4 5 2 3,最顶上的牌是1,把1拿走.剩余 4 5 2 3 第二轮: ...

  7. Zookeeper核心机制

    (如果感觉有帮助,请帮忙点推荐,添加关注,谢谢!你的支持是我不断更新文章的动力.本博客会逐步推出一系列的关于大型网站架构.分布式应用.设计模式.架构模式等方面的系列文章) Zookeeper是Hado ...

  8. HDU 4549 M斐波那契数列(矩阵幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4549 题意:F[0]=a,F[1]=b,F[n]=F[n-1]*F[n-2]. 思路:手算一下可以发现 ...

  9. Junit单元测试的实例

    进行单元测试的代码 package JunitTest; import org.junit.Test; public class Calculator { private static int res ...

  10. 在oracle中where 子句和having子句中的区别

    在oracle中where 子句和having子句中的区别 1.where 不能放在GROUP BY 后面 2.HAVING 是跟GROUP BY 连在一起用的,放在GROUP BY 后面,此时的作用 ...