存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,存储在数据库中,通过第一次编译后再次调用不须要再次编译,用户经过指定存储过程的名字并给出参数(若是该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象。数据库
CREATE proc | procedure procedure_name [{@参数数据类型} [=默认值] [output], {@参数数据类型} [=默认值] [output], .... ] as SQL_statements go
1.提升性能安全
SQL语句在建立过程时进行分析和编译。 存储过程是预编译的,在首次运行一个存储过程时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划,这样,在执行过程时即可节省此开销。
2.下降网络开销服务器
存储过程调用时只需用提供存储过程名和必要的参数信息,从而可下降网络的流量。
3.便于进行代码移植网络
数据库专业人员能够随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提升了程序的可移植性。
4.更强的安全性函数
1)系统管理员能够对执行的某一个存储过程进行权限限制,避免非受权用户对数据的访问 2)在经过网络调用过程时,只有对执行过程的调用是可见的。 所以,恶意用户没法看到表和数据库对象名称、嵌入本身的 Transact-SQL 语句或搜索关键数据 3)使用过程参数有助于避免 SQL 注入攻击。 由于参数输入被视做文字值而非可执行代码,因此,攻击者将命令插入过程内的 Transact-SQL 语句并损害安全性将更为困难 4)能够对过程进行加密,这有助于对源代码进行模糊处理
1.存储过程须要专门的数据库开发人员进行维护
2.设计逻辑变动,修改存储过程没有SQL灵活性能
N后字符串的数据类型为NChar或是NVarchar优化
在服务器上执行的代码中(例如在存储过程和触发器中)显示的 Unicode 字符串常量必须以大写字母 N 为前缀。即便所引用的列已定义为 Unicode 类型,也应如此。如不使用 N 前缀,字符串将转换为数据库的默认代码页。可能致使不识别某些字符加密
EXECUTE Product_Info @name = N'Chain'
使用 N 前缀的要求适用于在服务器上生成的和客户端发送的字符串常量设计
--查询存储过程 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
--执行 EXEC PROC_SELECT_STUDENTS_COUNT
--查询存储过程,根据城市查询总数 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
--执行 EXEC PROC_SELECT_STUDENTS_BY_CITY_COUNT N'Beijing'
在参数值赋值时,加上相应的通配符code
--查询姓氏为李的学生信息,含通配符 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
--执行 EXEC PROC_SELECT_STUDENTS_BY_SURNNAME EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'林%' EXEC PROC_SELECT_STUDENTS_BY_SURNNAME N'%林%'
--根据姓名查询的学生信息,返回学生的城市及年龄 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
--执行 declare @name nvarchar(50), @city nvarchar(20), @age int; set @name = N'PG ONE'; set @age = 23; exec PROC_SELECT_STUDENTS_BY_NAME @name, @city out, @age output; select @city, @age;
--存储过程:新增学生信息 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
--执行 EXEC PROC_INSERT_STUDENT 1001, N'GAI', 29, 'ChengDu'
--根据学生ID,更新学生信息 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 --执行 EXEC PROC_UPDATE_STUDENT 1001, N'Jony J', 28, 'NanChang'
--存储过程:删除学生信息 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
--执行 EXEC PROC_DELETE_STUDENT_BY_ID 1001
--分页查询 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
--执行 EXEC PROC_SELECT_BY_PAGE 1,10
--使用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
--执行 EXEC PROC_SELECT_BY_PAGE_WITH_TOP 1,2
--存储过程,重复编译 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
加密后,不能查看和修改源脚本
--查询存储过程,进行加密 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
--执行 EXEC PROC_SELECT_STUDENTS_WITH_ENCRYPTION