Sql 中蕴藏过程详细案例。存储过程。




转自:http://www.cnblogs.com/yank/p/4235609.html

概念

仓储过程(Stored
Procedure):已预编译为一个不过尽进程的一个或者多单SQL语句。 

概念

囤过程(Stored
Procedure):已预编译为一个只是实施进程的一个要多单SQL语句。 

创造存储过程语法

图片 1😉

CREATE proc | procedure procedure_name
    [{@参数数据类型} [=默认值] [output],
     {@参数数据类型} [=默认值] [output],
     ....
    ]
as
    SQL_statements go

图片 2😉

缔造存储过程语法

图片 3

CREATE proc | procedure procedure_name
    [{@参数数据类型} [=默认值] [output],
     {@参数数据类型} [=默认值] [output],
     ....
    ]
as
    SQL_statements
go

图片 4

囤过程以及SQL语句对比

优势:

1、提高性能 SQL语句以创立进程时展开分析和编译。
存储过程是预编译的,在首次运行一个仓储过程不时,查询优化器对该展开解析、优化,并被起最终给有网表中的贮存计划,这样,在履行过程不时即便只是节约此开。
2、降低网络开
存储过程调用时仅待用提供仓储过程叫及必要的参数信息,从而可降低网络的流量。
3、便于进行代码移植
数据库专业人员好天天对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的加强了次的可移植性。
4、更强的安全性
1)系统管理员可以针对执行之某一个储存过程进展权力限制,避免非授权用户对数据的拜访
2)在经过网调用过程不时,只有对推行进程的调用是可见的。
因此,恶意用户无法见到表和数据库对象名称、嵌入自己的 Transact-SQL
语句或探寻关键数据。 3)使用过程参数有助于避免 SQL 注入攻击。
因为参数输入被当文字值如果非可实施代码,所以,攻击者将指令插入过程外的
Transact-SQL 语句并损害安全性将尤为艰难。
4)可以对过程进行加密,这有助于对源代码进行模糊处理。 

劣势:

1、存储过程用专门的数据库开发人员进行保护,但实际情况是,往往由于程序开发员人员兼

2、设计逻辑变更,修改存储过程没有SQL灵活

存储过程和SQL语句对比

优势:

1、提高性
SQL语句以开立进程时开展辨析与编译。
存储过程是预编译的,在首糟糕运行一个仓储过程不时,查询优化器对那进展辨析、优化,并叫起最后被存在系统表中的囤计划,这样,在实施过程不时即只是节省此开。
2、降低网络开
储存过程调用时不过需要用提供仓储过程叫与必备之参数信息,从而可退网络的流量。
3、便于进行代码移植
数据库专业人员可以随时对存储过程进展改动,但对应用程序源代码却毫不影响,从而极大的增长了次的可移植性。
4、更胜之安全性
1)系统管理员可以针对推行之某一个存储过程进行权力限制,避免非授权用户指向数据的顾
2)在经网调用过程不时,只有对实行进程的调用是可见的。
因此,恶意用户无法观表和数据库对象名称、嵌入自己之 Transact-SQL
语句或找关键数据。
3)使用过程参数有助于避免 SQL 注入攻击。
因为参数输入被作为文字值如果无可实行代码,所以,攻击者将下令插入过程外的
Transact-SQL 语句并重伤安全性将进一步艰难。
4)可以针对经过进展加密,这有助于对源代码进行模糊处理。 

劣势:

1、存储过程用特别的数据库开发人员进行保障,但实际状况是,往往是因为程序开发员人员兼

2、设计逻辑变更,修改存储过程并未SQL灵活

缘何在实质上使用中,存储过程用到相对比较少呢?

在平常的型研发中,用存储过程倒相对比较少,这是干什么也? 分析由如下:
1)没有特定的数据库开发人员,普通程序员兼职进行数据库操作
2)程序员往往只有需要操作程序,即可到位多少访问,无需再次以数据库及开展开
3)项目需要变动比较频繁,修改SQL语句比较便于,特别是涉嫌逻辑变更 

缘何当实际利用中,存储过程用到相对较少为?

每当日常的型研发中,用存储过程也相对较少,这是为什么吗?
剖析由如下:
1)没有特定的数据库开发人员,普通程序员兼职进行数据库操作
2)程序员往往就待操作程序,即可成功数据访问,无需再当数据库及展开开
3)项目需要变动比较累,修改SQL语句比较便宜,特别是涉嫌逻辑变更 

囤过程以及SQL语句如何选?

根据实际用之涉,给予如下建议:

1、在局部赛效率要规范性要求比较大之类型,建议以储存过程
2、对于一般品种建议下参数化命令道,是储存过程和SQL语句一栽折中之艺术
3、对于有算法要求较高,涉及多长条数据逻辑,建议采用储存过程

 

储存过程和SQL语句如何选择?

基于实际行使的阅历,给予如下建议:

1、在部分胜似效率要规范性要求比较大之品类,建议采用储存过程
2、对于一般项目建议以参数化命令道,是储存过程与SQL语句一种折中的计
3、对于有些算法要求比强,涉及多修数据逻辑,建议采用储存过程

 

存储过程的有血有肉运用

 一、基础查询

1、创建不带参数的仓储过程

事例:查询学生总数

图片 5😉

--查询存储过程
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_COUNT', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_COUNT;
GO
CREATE procedure PROC_SELECT_STUDENTS_COUNT
AS 
    SELECT COUNT(ID) FROM Students
GO

图片 6😉

执行:

EXEC PROC_SELECT_STUDENTS_COUNT

 

2、带参数的蕴藏过程

图片 7😉

--查询存储过程,根据城市查询总数
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_CITY_COUNT', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT(@city nvarchar(50))
AS
    SELECT COUNT(ID) FROM Students WHERE City=@city
GO

图片 8😉

行语句:

EXEC PROC_SELECT_STUDENTS_BY_CITY_COUNT N'Beijing'

3、带有通配符

通配符,在参数值赋值时,加上相应的通配符

图片 9😉

--3、查询姓氏为李的学生信息,含通配符
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_SURNNAME', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_SURNNAME;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_SURNNAME
    @surnName nvarchar(20)='李%' --默认值
AS 
    SELECT ID,Name,Age FROM Students WHERE Name like @surnName
GO

图片 10😉

执行:

EXEC PROC_SELECT_STUDENTS_BY_SURNNAME
EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'李%'
EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'%李%'

 

4、带有输出参数

图片 11😉

--根据姓名查询的学生信息,返回学生的城市及年龄
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_NAME', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_NAME;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_NAME
    @name nvarchar(50),     --输入参数
    @city nvarchar(20) out, --输出参数
    @age  int output        --输入输出参数
AS 
    SELECT @city=City,@age=Age FROM Students WHERE Name=@name AND Age=@age
GO

图片 12😉

执行:

图片 13😉

--执行
declare @name nvarchar(50),
        @city nvarchar(20),
        @age int;
set @name = N'李明';
set @age = 20;
exec PROC_SELECT_STUDENTS_BY_NAME @name,@city out, @age output;
select @city, @age;

图片 14😉

老二、使用存储过程进展追加删改

1、新增

新增学生信息 

图片 15😉

--1、存储过程:新增学生信息
IF OBJECT_ID (N'PROC_INSERT_STUDENT', N'P') IS NOT NULL
    DROP procedure PROC_INSERT_STUDENT;
GO
CREATE procedure PROC_INSERT_STUDENT
    @id int,
    @name nvarchar(20),
    @age int,
    @city nvarchar(20)
AS 
    INSERT INTO Students(ID,Name,Age,City) VALUES(@id,@name,@age,@city)
GO

图片 16😉

 执行:

EXEC PROC_INSERT_STUDENT 1001,N'张三',19,'ShangHai'

2、修改

依据学生ID,更新学生信息 

图片 17😉

IF OBJECT_ID (N'PROC_UPDATE_STUDENT', N'P') IS NOT NULL
    DROP procedure PROC_UPDATE_STUDENT;
GO
CREATE procedure PROC_UPDATE_STUDENT
    @id int,
    @name nvarchar(20),
    @age int,
    @city nvarchar(20)
AS 
    UPDATE Students SET Name=@name,Age=@age,City=@city WHERE ID=@id
GO

图片 18😉

执行:

EXEC PROC_UPDATE_STUDENT 1001,N'张思',20,'ShangHai'

 

3、删除

基于ID,删除某学生记录

图片 19😉

--3、存储过程:删除学生信息
IF OBJECT_ID (N'PROC_DELETE_STUDENT_BY_ID', N'P') IS NOT NULL
    DROP procedure PROC_DELETE_STUDENT_BY_ID;
GO
CREATE procedure PROC_DELETE_STUDENT_BY_ID
    @id int
AS 
    DELETE FROM  Students WHERE ID=@id
GO

图片 20😉

执行:

EXEC PROC_DELETE_STUDENT_BY_ID 1001

 

 三、存储过程实现分页查询

1、使用row_number函数分页

图片 21😉

--分页查询
IF OBJECT_ID (N'PROC_SELECT_BY_PAGE', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_BY_PAGE;
GO
CREATE procedure PROC_SELECT_BY_PAGE
    @startIndex int,
    @endIndex int
AS 
    SELECT  * FROM (SELECT ID,Name,Age,City,ROW_NUMBER() OVER(ORDER BY ID DESC) AS RowNumber FROM Students) AS Temp 
    WHERE Temp.RowNumber BETWEEN @startIndex AND @endIndex
GO

图片 22😉

执行:

EXEC PROC_SELECT_BY_PAGE 1,10

2、使用传统的top分页

图片 23😉

--使用TOP分页
IF OBJECT_ID (N'PROC_SELECT_BY_PAGE_WITH_TOP', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_BY_PAGE_WITH_TOP;
GO
CREATE procedure PROC_SELECT_BY_PAGE_WITH_TOP
    @pageIndex int,
    @pageSize int
AS 
    SELECT TOP(@pageSize) * FROM Students 
    WHERE ID >=(SELECT MAX(ID) FROM (SELECT TOP(@pageSize*(@pageIndex-1) + 1) ID FROM Students ORDER BY ID) AS Temp)    
GO

图片 24😉

执行:

EXEC PROC_SELECT_BY_PAGE_WITH_TOP 1,2

 

季、其他功能:

1、存储过程,每次执行都进展更编译

图片 25😉

--1、存储过程,重复编译
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_RECOMPILE', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE;
GO
CREATE procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE
with recompile --重复编译
AS 
    SELECT * FROM Students
GO

图片 26😉

 

2、对存储过程进展加密

加密后,不克查看和修改源脚本

图片 27😉

--2、查询存储过程,进行加密
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_ENCRYPTION', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION;
GO
CREATE procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION
with encryption --加密
AS 
    SELECT * FROM Students
GO

图片 28😉

执行:

EXEC PROC_SELECT_STUDENTS_WITH_ENCRYPTION

功能,无法查看脚本或者导出创建脚本

图片 29

 

积存过程的现实用

 一、基础查询

1、创建不带来参数的囤过程

事例:查询学生总数

图片 30

--查询存储过程
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_COUNT', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_COUNT;
GO
CREATE procedure PROC_SELECT_STUDENTS_COUNT
AS 
    SELECT COUNT(ID) FROM Students
GO

图片 31

执行:

EXEC PROC_SELECT_STUDENTS_COUNT

 

2、带参数的仓储过程

图片 32

--查询存储过程,根据城市查询总数
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_CITY_COUNT', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_CITY_COUNT(@city nvarchar(50))
AS
    SELECT COUNT(ID) FROM Students WHERE City=@city
GO

图片 33

推行语句:

EXEC PROC_SELECT_STUDENTS_BY_CITY_COUNT N'Beijing'

3、带有通配符

通配符,在参数值赋值时,加上相应的通配符

图片 34

--3、查询姓氏为李的学生信息,含通配符
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_SURNNAME', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_SURNNAME;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_SURNNAME
    @surnName nvarchar(20)='李%' --默认值
AS 
    SELECT ID,Name,Age FROM Students WHERE Name like @surnName
GO

图片 35

执行:

EXEC PROC_SELECT_STUDENTS_BY_SURNNAME
EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'李%'
EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'%李%'

 

4、带有输出参数

图片 36

--根据姓名查询的学生信息,返回学生的城市及年龄
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_BY_NAME', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_BY_NAME;
GO
CREATE procedure PROC_SELECT_STUDENTS_BY_NAME
    @name nvarchar(50),     --输入参数
    @city nvarchar(20) out, --输出参数
    @age  int output        --输入输出参数
AS 
    SELECT @city=City,@age=Age FROM Students WHERE Name=@name AND Age=@age
GO

图片 37

执行:

图片 38

--执行
declare @name nvarchar(50),
        @city nvarchar(20),
        @age int;
set @name = N'李明';
set @age = 20;
exec PROC_SELECT_STUDENTS_BY_NAME @name,@city out, @age output;
select @city, @age;

图片 39

亚、使用存储过程进行加删改

1、新增

新增学生信息 

图片 40

--1、存储过程:新增学生信息
IF OBJECT_ID (N'PROC_INSERT_STUDENT', N'P') IS NOT NULL
    DROP procedure PROC_INSERT_STUDENT;
GO
CREATE procedure PROC_INSERT_STUDENT
    @id int,
    @name nvarchar(20),
    @age int,
    @city nvarchar(20)
AS 
    INSERT INTO Students(ID,Name,Age,City) VALUES(@id,@name,@age,@city)
GO

图片 41

 执行:

EXEC PROC_INSERT_STUDENT 1001,N'张三',19,'ShangHai'

2、修改

据悉学生ID,更新学生信息 

图片 42

IF OBJECT_ID (N'PROC_UPDATE_STUDENT', N'P') IS NOT NULL
    DROP procedure PROC_UPDATE_STUDENT;
GO
CREATE procedure PROC_UPDATE_STUDENT
    @id int,
    @name nvarchar(20),
    @age int,
    @city nvarchar(20)
AS 
    UPDATE Students SET Name=@name,Age=@age,City=@city WHERE ID=@id
GO

图片 43

执行:

EXEC PROC_UPDATE_STUDENT 1001,N'张思',20,'ShangHai'

 

3、删除

根据ID,删除某学生记录

图片 44

--3、存储过程:删除学生信息
IF OBJECT_ID (N'PROC_DELETE_STUDENT_BY_ID', N'P') IS NOT NULL
    DROP procedure PROC_DELETE_STUDENT_BY_ID;
GO
CREATE procedure PROC_DELETE_STUDENT_BY_ID
    @id int
AS 
    DELETE FROM  Students WHERE ID=@id
GO

图片 45

执行:

EXEC PROC_DELETE_STUDENT_BY_ID 1001

 

 三、存储过程实现分页查询

1、使用row_number函数分页

图片 46

--分页查询
IF OBJECT_ID (N'PROC_SELECT_BY_PAGE', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_BY_PAGE;
GO
CREATE procedure PROC_SELECT_BY_PAGE
    @startIndex int,
    @endIndex int
AS 
    SELECT  * FROM (SELECT ID,Name,Age,City,ROW_NUMBER() OVER(ORDER BY ID DESC) AS RowNumber FROM Students) AS Temp 
    WHERE Temp.RowNumber BETWEEN @startIndex AND @endIndex
GO

图片 47

执行:

EXEC PROC_SELECT_BY_PAGE 1,10

2、使用传统的top分页

图片 48

--使用TOP分页
IF OBJECT_ID (N'PROC_SELECT_BY_PAGE_WITH_TOP', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_BY_PAGE_WITH_TOP;
GO
CREATE procedure PROC_SELECT_BY_PAGE_WITH_TOP
    @pageIndex int,
    @pageSize int
AS 
    SELECT TOP(@pageSize) * FROM Students 
    WHERE ID >=(SELECT MAX(ID) FROM (SELECT TOP(@pageSize*(@pageIndex-1) + 1) ID FROM Students ORDER BY ID) AS Temp)    
GO

图片 49

执行:

EXEC PROC_SELECT_BY_PAGE_WITH_TOP 1,2

 

季、其他职能:

1、存储过程,每次执行都开展双重编译

图片 50

--1、存储过程,重复编译
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_RECOMPILE', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE;
GO
CREATE procedure PROC_SELECT_STUDENTS_WITH_RECOMPILE
with recompile --重复编译
AS 
    SELECT * FROM Students
GO

图片 51

 

2、对存储过程进展加密

加密后,不可知查看和修改源脚本

图片 52

--2、查询存储过程,进行加密
IF OBJECT_ID (N'PROC_SELECT_STUDENTS_WITH_ENCRYPTION', N'P') IS NOT NULL
    DROP procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION;
GO
CREATE procedure PROC_SELECT_STUDENTS_WITH_ENCRYPTION
with encryption --加密
AS 
    SELECT * FROM Students
GO

图片 53

执行:

EXEC PROC_SELECT_STUDENTS_WITH_ENCRYPTION

功能,无法查看脚本或者导出创建脚本

图片 54

 

笔者介绍:半路学IT,做开发3年,先下车于同寒共享单车店,做后台开发!

 我开了一个公众号,欢迎各位有志同道合朋友,关注!不定期分享工作,和我得故事!

图片 55

分类: 数据库技术

相关文章