sql学习笔记--存储过程

 存储过程(stored procedure)有时也称sproc,它是真正的脚本,更准确地说,它是批处理(batch),但都不是很确切,它存储与数据库而不是单独的文件中。

  存储过程中有输入参数,输出参数以及返回值等。

一、创建存储过程

  创建存储过程的方法和创建数据库中任何其他对象一样,除了他使用AS关键字外。存储过程的基本语法如下:

  CREATE PROCEDURE|PROC <sproc name>
  [<parameter name> [schema.] <data type> [VARYING] [=<default value>] [OUT[PUT]] [READONLY]
  [,<parameter name> [schema.] <data type> [VARYING] [=<default value>] [OUT[PUT]] [READONLY]
  [,...
  ...
  ]]
  [WITH
  RECOMPILE | ENCRYPTION | [EXECUTE AS { CALLER | SELF | OWNER | <‘user name‘>}]
  AS
  <code> | EXTERNAL NAME <assembly name>.<assembly class>.<method>

  在语法中,PROC是PROCEDURE的缩写,两个选项的意思一样。

  在对存储过程命名完之后,接着是参数列表。参数是可选的。

  关键字AS其后就是实际的代码。

  简单的存储过程示例:

  CREATE PROC spPerson
  AS
  SELECT * FROM Person

  执行存储过程:

  EXEC spPerson

  查看结果:

  

二、ALTER修改存储过程

  ALTER PROC和CREATE PROC的区别如下:

  •   ALTER PROC期望找到一个已有的存储过程,而CREATE则不是。
  •   ALTER PROC保留了存储过程上已经建立的任何权限。它在系统对象中保留了对象Id并允许保留依赖关系。例如,如果过程A调用过程B,如果删除并重建B,那么就不能在看到这两者间的依赖关系。如果使用ALTER,则依赖关系仍然存在。
  •   ALTER PROC在可能调用被修改的存储过程的其他对象上保留了任何依赖信息。

  示例:

  ALTER PROC spPerson
  AS
  SELECT * FROM Person WHERE Id = 45

三、删除存储过程

  删除存储过程的语法最简单:

  DROP PROC|PROCEDURE <sproc name>[;]

  这样就完成了存储过程的删除。

四、参数化

  如果存储过程没有办法接受一些数据,告诉其要完成的任务,则在大多数情况下,存储过程不会有太大帮助。例如,要删除一条数据,但却不指定Id,则存储过程也不知道要删除哪条,所以使用输入参数非常有必要。

  1、声明参数

  声明参数需要以下2到4部分的信息:

  •   名称
  •   数据类型
  •   默认值
  •   方向

  其语法如下所示:

  @parameter_name [AS] datatype [=default|NULL] [VARYING] [OUTPUT | OUT]

  对于名称,有一组简单的规则。首先,它必须以@符号(和变量一样)开始。此外,除了不能内嵌空格外,其规则与普通变量规则相同。

  数据类型和名称一样,必须像变量那样声明,采用SQL Server内置的或用户自定义的数据类型。

  声明需要类型时需要注意,当声明CURSOR类型参数时,必须也使用VARYING和OUTPUT选项。同时,OUTPUT可以简写为OUT。

  在默认值方面,参数与变量不同。对于同样的情况,变量一般初始化为NULL值,而参数不是。事实上,如果不提供默认则,则会假设参数是必须的,并且当调用存储过程时需要提供一个初始值。

  一个需要传入参数的存储过程示例:

  CREATE PROC spName
    @Name nvarchar(50)
  AS
  SELECT Name FROM Person
  WHERE Name LIKE @Name + ‘%‘;

  执行存储过程:

  EXEC spName ‘酒‘;

  显示结果如下:

  

  2、提供默认值

  为了使参数是可选的,必须提供默认值。方法是在数据类型后在逗号之前添加"="符号和作为默认值的值。这样,存储过程的用户尅有决定对此参数不提供值或是提供他们自己的值。

  创建一个存储过程如下:

  CREATE PROC spName
  @Name nvarchar(50) = NULL
  AS
  IF @Name IS NOT NULL
      SELECT * FROM Person WHERE NAME = @Name
  ELSE
      SELECT * FROM Person WHERE Id = 45

  执行如下语句:

  EXEC spName
  EXEC spName ‘如意刀狼‘

  输出结果如下:

  

  3、输出参数

  下面来看看一个获得OUTPUT参数的存储过程:

  CREATE PROC InsertPerson
      @Id int OUTPUT  --必须注明为OUTPUT
  AS
  INSERT INTO Person
  VALUES(‘刘备‘,22,190,‘不详‘,‘未婚‘,‘幼儿园‘,‘不详‘,4999999)
  SET @Id = @@IDENTITY

  执行存储过程:

  DECLARE @Id int  --实际上,调用时名称可以不同,例如也可以为@Num,@i等等。
  EXEC InsertPerson @Id OUTPUT    --注意此处也要有OUTPUT
  SELECT @Id

  显示结果如下:

  

  对于存储过程本身以及调用脚本对它的使用,需要注意以下几点:

  • 对于存储过程声明中的输出参数,需要使用OUTPUT关键字。
  • 和声明存储过程时一样,调用存储过程时,必须使用OUTPUT关键字。这样就对SQL Server作了提前通知,告诉它参数所需要的特殊处理。但需要注意的是,如果忘记包含OUTPUT关键字,不会产生运行时错误,但是输出的值不会传入变量中(变量很可能是NULL)。
  • 赋值给输出结果的变量不需要和存储过程中的内部参数拥有相同的名称。
  • EXEC(或EXECUTE)关键字是必须的,因为对存储过程的调用并不是批处理要做的第一件事(如果存储过程的调用是批处理的第一件事,则可以不使用EXEC)。

五、返回值

  返回值的用途非常广泛,例如,返回数据,标识值或是存储过程影响的行数等等。而其实际作用是返回值可用来确定存储过程执行的状态。

  事实上,不管是否提供返回值,程序都会收到一个返回值。SQL Server默认会在完成存储过程时自动返回一个0值。

  为了从存储过程向调用代码传递返回值,只需要使用RETURN语句。

  RETURN [<integer value to return>]

  要特别注意的是:返回值必须是整数

  关于RETURN语句,最重要的是知道它是无条件地从存储过程中退出的。无论运行到存储过程的哪个位置,在调用RETURN语句之后将不会执行任何一行代码。

  这里的无条件,并不是说无论执行到代码的何处都将执行RETURN语句。相反,可以再存储过程中有多个RETURN语句。只有当代码的标准条件结构发出命令的时候,才会执行这些RETURN语句。一旦发生,就不能再退回了。

  创建一个存储过程如下:

  CREATE PROC spTestReturns
  AS
  DECLARE @MyMessage nvarchar(50);
  DECLARE @MyOtherMessage nvarchar(50);

  SELECT @MyMessage = ‘第一个RETURN‘;
  PRINT @MyMessage;
  RETURN;

  SELECT @MyOtherMessage = ‘第二个RETURN‘;
  PRINT @MyOtherMessage;
  RETURN;

  执行存储过程,输出如下:

  

  为了能捕获RETURN语句的值,需要在EXEC语句中把值赋给变量。例如:

  DECLARE @Return int
  EXEC @Return = spTestReturns
  SELECT @Return

  输出如下:

  

  虽然简单但是还不错。当运行时,可以看到RETURN语句却是在运行其他代码前终止了代码运行。

  如果总是返回0,那么执行成不成功都不知道,那么我们现在来改写下上面的存储过程,让其返回一个指定的值,以指示执行状态。

  CREATE PROC spTestReturns
  AS
  DECLARE @MyMessage nvarchar(50);
  DECLARE @MyOtherMessage nvarchar(50);

  SELECT @MyMessage = ‘第一个RETURN‘;
  PRINT @MyMessage;
  RETURN 100;        --将这里改成返回100

  SELECT @MyOtherMessage = ‘第二个RETURN‘;
  PRINT @MyOtherMessage;
  RETURN;

  执行之后,显示结果如下:

  

六、存储过程的优缺点

  存储过程的主要优点包括以下几个方面:

  •   使得需要过程式动作的进程可调用
  •   安全性
  •   性能

  1、创建可调用的进程

  很多人并没有意识到要充分使用存储过程,使其作为实现安全性的工具。和视图类似,可以创建一个返回记录集的存储过程而不用赋予用户访问底层数据表的权限。赋予某人执行一个存储过程的权限意味着他们可以在该存储过程中执行任何动作。不过要假设动作是在存储过程的上下文中执行的。

  2、存储过程和性能

  一般来说,存储过程有助于系统性能的提高。但是,如果设计的存储过程缺乏只能,那么它会使在其创建的进程变得非常缓慢。

  存储过程的运行示意图如下:

  

  首先运行CREATE PROC过程。这回解析查询以确保会实际运行这些代码。它与直接运行脚本的区别在于CREATE PROC命令可以利用所谓的延迟名称解析。延迟名称解析可以忽略一些对象还不存在的事实。

  在创建了存储过程后,它将等待第一次执行。在那时,存储过程被优化,而查询计划被编译并且缓存到系统上。后续几次运行该存储过程时,除非通过使用WITH RECOMPILE选项指定,否则都会使用缓存的查询计划而不是创建一个新的查询计划。这意味着每次使用该存储过程时,存储过程都会跳过很多优化和编译工作。节省的确切时间取决于批处理的复杂性,批处理中表的大小,以及每个表上索引的数量。通常,节省的时间不是很多。但对于大多数场景来说可能是1秒或更少-但通过百分比可以计算出此区别(1秒比2秒快了100%)。当需要进行多次调用时或针对循环的情况,这一区别会变得更明显。

  3、存储过程的不利方面

  对于存储过程的不利之处要认识到的最重要的一点事,除非手动地干预(使用WITH RECOMPILE选项),否则只会在第一次运行存储过程的时候,或者当查询所涉及的表更新了统计信息时,才对存储过程进行优化。
  这种"一次优化,多次使用"的策略节省了存储过程的时间,但是该策略也是一把双刃剑。如果查询是动态的(即是在使用EXEC命令时建立的),那么只会在第一次运行时对存储过程进行优化,但是会发现以后再也不这样了。简而言之,可能会使用错误的计划。

  4、WITH RECOMPILE选项

  可以利用存储过程提供的安全性代码和代码封装方面的好处,但还是忽略了预编译代码方面的影响。可以回避未使用正确的查询计划的问题,因为可以确保为特定一次运行创建新的计划。方法就是使用WITH RECOMPILE选项。
  使用该选项的方式有两种:

  1、可以在运行时包含WITH RECOMPILE。

  EXEC spMySproc ‘1/1/2004‘
  WITH RECOMPILE

  这告诉SQL Server抛弃已有的执行计划并且创建一个新的计划-但只是这一次。也就是说,只是这次使用WITH RECOMPILE选项来执行存储过程。

  也可以通过在存储过程中包含WITH RECOMPILE选项来使之变得更持久。如果使用这种方式,则在CREATE PROC或ALTER PROC语句中的AS语句前添加WITH RECOMPILE选项即可。

  如果通过该选项创建存储过程,那么无论在运行时选择了其他什么选项,每次运行存储过程都会重新编译它。

时间: 2024-10-16 02:13:10

sql学习笔记--存储过程的相关文章

Oracle之PL/SQL学习笔记之触发器

Oracle之PL/SQL学习笔记之触发器 触发器是许多关系数据库系统都提供的一项技术.在ORACLE系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的PL/SQL块. 触发器在数据库里以独立的对象存储,它与存储过程和函数不同的是,存储过程与函数需要用户显示调用才执行,而触发器是由一个事件来启动运行. 即触发器是当某个事件发生时自动地隐式运行.并且,触发器不能接收参数.所以运行触发器就叫触发或点火(firing).ORACLE事件指的是对数据库的表进行的INSERT. UPDATE及D

Oracle之PL/SQL学习笔记

自己在学习Oracle是做的笔记及实验代码记录,内容挺全的,也挺详细,发篇博文分享给需要的朋友,共有1w多字的学习笔记吧.是以前做的,一直在压箱底,今天拿出来整理了一下,给大家分享,有不足之处还望大家批评指正. PL/SQL定义:PL/SQL是由Oracle开发,专门用于Oracle的程序设计语言. PL---Procedural Language. SQL—Structure QueryLanguage.PL/SQL包括过程化语句和SQL语句     PL/SQL的单位:块. 一个块中可以嵌套

SQL学习笔记:选取第N条记录

Northwind数据库,选取价格第二高的产品. 有两种方法,一个是用Row_Number()函数: SELECT productname FROM (SELECT TOP 2 productname, Row_Number() OVER (ORDER BY unitprice desc) AS rownum FROM Products) AS tbl WHERE rownum = 2; 另一种是对子语句的的结果再进行排序: SELECT top 1 productname FROM (SELE

Oracle之PL/SQL学习笔记之数据类型(三)

Oracle之PL/SQL学习笔记之数据类型(三) 所有的编程语言中变量是使用最频繁的.PL/SQL作为一个面向过程的数据库编程语言同样少不了变量,利用变量可以把PL/SQL块需要的参数传递进来,做到动态执行程序,同时也可以利用变量在PL/SQL内部进行值得传递,甚至可以把值传递出去,最终返回给用户,由此可见,变量是PL/SQL不可或缺的一部分. 1. Oracle预定义的普通数据类型(常见的数据类型) 类型 子类 说明 Oracle中的范围 char Character,String Rowi

SQL学习笔记&mdash;&mdash;导论

果然虽然不努力不一定成功但是放弃了就会很轻松--嗯,acm的道路就此走到头了,虽然可能后面会有点小插曲但是从此以后走向刷绩点的道路这是可以肯定的了. SQL的学习笔记是以数据库系统概念的英文原本为主题的整理和翻译,分为sql的使用类型和数据库概念的解析类型.sql的使用类型里一般会带有实例,数据库概念大概就是一些翻译和总结,大概一篇对应原书的20页吧,不过可能会有修改. 反正写了也没有人看啊233

sql学习笔记1

参考: 1.<SQL学习指南> 2.慕课网,SQL学习基础 提纲: 第二章 创建和使用数据库 2.1 创建MYSQL数据库 2.2 使用mysql命令行工具 2.3 MySQL数据类型 2.3.1 字符型数据 2.3.2 数值型数据 2.3.3 时间数据 2.4 表的创建 2.4.1 第一步:设计 2.4.2 第二步:精华 2.4.3 第三步:构建SQL方案语句 2.5 操作和修改表 2.5.1 插入数据 2.5.2 更新数据 2.5.3 删除数据 2.6 导致错误的语句 2.6.1 主键不唯

sql学习笔记2

<SQL学习指南>第9章 子查询 参考:leetcode 2 ---------------------- 9.1 啥是子查询 9.2 子查询的类型 基于结果集的类型:单行/单列,单行/多列,多行/多列 完全独立的(非关联子查询).引用包含语句中的列(关联查询) 9.3 非关联子查询 前面讲的都是非关联的,可以的单独执行而不需要引用包含语句中的任何的内容.我们遇到的大多数的子查询都是这种类型,但是更新或者 删除语句会经常遇到关联子查询. 另外一个特点,前面的子查询除了是非关联的外,返回的都是一

PL/SQL学习笔记_03_存储函数与存储过程

ORACLE 提供可以把 PL/SQL 程序存储在数据库中,并可以在任何地方来运行它.这样就叫存储过程或函数. 存储函数:有返回值,创建完成后,通过select function() from dual;执行 存储过程:由于没有返回值,创建完成后,不能使用select语句,只能使用pl/sql块执行 一.存储函数 1.存储函数语法格式 CREATE [OR REPLACE] FUNCTION function_name [ (argment [ { IN | IN OUT } ] Type, a

sql学习笔记(16)----------mysql存储过程详解

mysql存储过程详解 1.     存储过程简介   我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它. 一个存储过程是一个可编程的函数,它在数据库中创建并保存.它可以有SQL语句和一些特殊的控制结构组成.当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的.