Transact-SQL中的存储过程,很是相似于Java语言中的方法,它能够重复调用。当存储过程执行一次后,能够将语句缓存中,这样下次执行的时候直接使用缓存中的语句。这样就能够提升存储过程的性能。数据库
Ø 存储过程的概念编程
存储过程Procedure是一组为了完成特定功能的SQL语句集合,经编译后存储在数据库中,用户经过指定存储过程的名称并给出参数来执行。缓存
存储过程当中能够包含逻辑控制语句和数据操纵语句,它能够接受参数、输出参数、返回单个或多个结果集以及返回值。安全
因为存储过程在建立时即在数据库服务器上进行了编译并存储在数据库中,因此存储过程运行要比单个的SQL语句块要快。同时因为在调用时只需用提供存储过程名和必要的参数信息,因此在必定程度上也能够减小网络流量、简单网络负担。服务器
一、 存储过程的优势网络
A、 存储过程容许标准组件式编程性能
存储过程建立后能够在程序中被屡次调用执行,而没必要从新编写该存储过程的SQL语句。并且数据库专业人员能够随时对存储过程进行修改,但对应用程序源代码却毫无影响,从而极大的提升了程序的可移植性。fetch
B、 存储过程可以实现较快的执行速度优化
若是某一操做包含大量的T-SQL语句代码,分别被屡次执行,那么存储过程要比批处理的执行速度快得多。由于存储过程是预编译的,在首次运行一个存储过程 时,查询优化器对其进行分析、优化,并给出最终被存在系统表中的存储计划。而批处理的T-SQL语句每次运行都须要预编译和优化,因此速度就要慢一些。加密
C、 存储过程减轻网络流量
对于同一个针对数据库对象的操做,若是这一操做所涉及到的T-SQL语句被组织成一存储过程,那么当在客户机上调用该存储过程时,网络中传递的只是该调用语句,不然将会是多条SQL语句。从而减轻了网络流量,下降了网络负载。
D、 存储过程可被做为一种安全机制来充分利用
系统管理员能够对执行的某一个存储过程进行权限限制,从而可以实现对某些数据访问的限制,避免非受权用户对数据的访问,保证数据的安全。
Ø 系统存储过程
系统存储过程是系统建立的存储过程,目的在于可以方便的从系统表中查询信息或完成与更新数据库表相关的管理任务或其余的系统管理任务。系统存储过程主要存 储在master数据库中,以“sp”下划线开头的存储过程。尽管这些系统存储过程在master数据库中,但咱们在其余数据库仍是能够调用系统存储过 程。有一些系统存储过程会在建立新的数据库的时候被自动建立在当前数据库中。
经常使用系统存储过程有:
sp_databases; --查看数据库 sp_tables; --查看表 sp_columns student;--查看列 sp_helpIndex student;--查看索引 sp_helpConstraint student;--约束 sp_stored_procedures; sp_helptext ;--查看存储过程建立、定义语句 sp_rename student, stuInfo;--修改表、索引、列的名称 sp_renamedb myTempDB, myDB;--更改数据库名称 sp_defaultdb , ;--更改登陆名的默认数据库 sp_helpdb;--数据库帮助,查询数据库信息 sp_helpdb master;
系统存储过程示例:
--表重命名 sp_rename , ; * stud; --列重命名 sp_rename , , ; sp_help ; --重命名索引 sp_rename N, N, N; sp_help ; --查询全部存储过程 * sys.objects type = ; * sys.objects type_desc name ;
Ø 用户自定义存储过程
一、 建立语法
| pro_name [{@参数数据类型} [=默认值] [], {@参数数据类型} [=默认值] [], .... ] SQL_statements
二、 建立不带参数存储过程
--建立存储过程 ( ( * sys.objects name = )) proc_get_student proc_get_student * student; --调用、执行存储过程 proc_get_student;
三、 修改存储过程
--修改存储过程 proc_get_student * student;
四、 带参存储过程
--带参存储过程 (object_id(, ) ) proc_find_stu proc_find_stu(@startId , @endId ) * student id @startId @endId proc_find_stu 2, 4;
五、 带通配符参数存储过程
--带通配符参数存储过程 (object_id(, ) ) proc_findStudentByName proc_findStudentByName(@name (20) = , @nextName (20) = ) * student name @name name @nextName; proc_findStudentByName; proc_findStudentByName , ;
六、 带输出参数存储过程
(object_id(, ) ) proc_getStudentRecord proc_getStudentRecord( @id , --默认输入参数 @name (20) , --输出参数 @age (20) --输入输出参数 ) @name = name, @age = age student id = @id sex = @age; @id , @name (20), @temp (20); @id = 7; @temp = 1; proc_getStudentRecord @id, @name , @temp ; @name, @temp; @name + + @temp;
七、 不缓存存储过程
-- RECOMPILE 不缓存 (object_id(, ) ) proc_temp proc_temp recompile * student; proc_temp;
八、 加密存储过程
--加密WITH ENCRYPTION (object_id(, ) ) proc_temp_encryption proc_temp_encryption encryption * student; proc_temp_encryption; sp_helptext ; sp_helptext ;
九、 带游标参数存储过程
(object_id(, ) ) proc_cursor proc_cursor @cur @cur = forward_only id, name, age student; @cur; --调用 @exec_cur ; @id , @name (20), @age ; proc_cursor @cur = @exec_cur ;--调用存储过程 @exec_cur @id, @name, @age; (@@fetch_status = 0) @exec_cur @id, @name, @age; + (, @id) + + @name + + (, @age); @exec_cur; @exec_cur;--删除游标
十、 分页存储过程
---存储过程、row_number完成分页 (object_id(, ) ) proc_cursor pro_page @startIndex , @endIndex (*) product ; * ( row_number() ( pid) rowId, * product ) temp temp.rowId @startIndex @endIndex -- pro_page pro_page 1, 4 (object_id(, ) ) pro_stu pro_stu( @pageIndex , @pageSize ) @startRow , @endRow @startRow = (@pageIndex - 1) * @pageSize +1 @endRow = @startRow + @pageSize -1 * ( *, row_number() ( id ) number student ) t t.number @startRow @endRow; pro_stu 2, 2;
Ø Raiserror
Raiserror返回用户定义的错误信息,能够指定严重级别,设置系统变量记录所发生的错误。
语法以下:
({msg_id | msg_str | @local_variable} {, severity, } [,argument[,…n]] [ [,…n]] )
# msg_id:在sysmessages系统表中指定的用户定义错误信息
# msg_str:用户定义的信息,信息最大长度在2047个字符。
# severity:用户定义与该消息关联的严重级别。当使用msg_id引起使用sp_addmessage建立的用户定义消息时,raiserror上指定严重性将覆盖sp_addmessage中定义的严重性。
任何用户能够指定0-18直接的严重级别。只有sysadmin固定服务器角色经常使用或具备alter trace权限的用户才能指定19-25直接的严重级别。19-25之间的安全级别须要使用with log选项。
# state:介于1至127直接的任何整数。State默认值是1。
(, 16, 1); * sys.messages; --使用sysmessages中定义的消息 (33003, 16, 1); (33006, 16, 1);