zoukankan      html  css  js  c++  java
  • sql server存储过程编程

    存储过程是一组完成特定功能的SQL 语句集合,经编译后存储在数据库中。
     
    存储过程作为一个单元进行处理并以一个名称来标识。它能向用户返回数据、向数据库表中写入或修改数据等操作。
    用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
     
     

    存储过程的作用

    执行速度快;
    减少网络流量;
    作为一种安全机制。通过设置用户只可能使用存储过程访问数据,限制用户不能直接操作数据库中的敏感数据,以保障数据的安全性;
    屏蔽T-SQL命令,提供交互查询的客户接口,增加数据库应用的方便性。
     
     

    存储过程和函数的异同

     
    本质上没区别。
    不同:
    函数只能返回一个变量的限制。而存储过程可以返回多个。
    函数是可以嵌入在SQL中使用的,可以在select中调用,而存储过程不行。
     
     

    存储过程的种类

    1. 系统存储过程  

       系统存储过程由系统提供,在安装SQL Server 2008 后自动装入,定义在系统数据master中,其存储过程名前缀是sp_。

    2.  扩展存储过程 

       扩展存储过程用windows动态链接库实现,任何能够创建动态链接库的编程工具都可以用于创建扩展存储过程的dll,这就使得扩展存储过程的功能不收SQL语句的限制。其存储过程名前缀是xp_。

    3.用户自定义存储过程

           用户自定义存储过程是在用户数据库中创建的存储过程,用以完成特定的数据库操作任务,也称为用户存储过程。本地存储过程通常只能应用于创建它的数据库,并且存储过程名不能使用sp_前缀,以免系统误解。

    永久存储过程
    临时存储过程
    前缀“#”:局部临时存储过程
    前缀“##”:全局临时存储过程
     
    例如:
     1 SET ANSI_NULLS ON
     2 GO
     3 SET QUOTED_IDENTIFIER ON
     4 GO
     5 /*上两句是 SQL-92 设置语句,使 SQL Server 2000/2005/2008 遵从 SQL-92 规则。 
     6 --当 SET QUOTED_IDENTIFIER 为 ON 时,标识符可以由双引号分隔,
     7 而文字必须由单引号分隔。当 SET QUOTED_IDENTIFIER 为 OFF 时,
     8 标识符不可加引号,且必须符合所有 Transact-SQL 标识符规则。 
     9 SQL-92 标准要求在对空值进行等于 (=) 或不等于 (<>) 比较时取值为 FALSE。
    10 当 SET ANSI_NULLS 为 ON 时,即使 column_name 中包含空值,
    11 使用 WHERE column_name = NULL 的 SELECT 语句仍返回零行。
    12 即使 column_name 中包含非空值,使用 WHERE column_name <> NULL 的 
    13 SELECT 语句仍会返回零行。 
    14 --当 SET ANSI_NULLS 为 OFF 时,等于 (=) 和不等于 (<>) 比较运算符不遵从 
    15 SQL-92 标准。使用 WHERE column_name = NULL 的 SELECT 语句返回 column_name
    16 中包含空值的行。使用 WHERE column_name <> NULL 的 SELECT 语句返回列中包含非空值的行。此外,使用 WHERE column_name <> XYZ_value 的 SELECT 语句返回所有不为 XYZ_value 也不为 NULL 的行。 
    17 */
    18 -----------------------
    19 
    20 SET ANSI_NULLS ON    --用于和NULL的比较,如:null=null在off时会返回true,在on时为false   
    21 SET QUOTED_IDENTIFIER ON  --
    22 go
    23 
    24 use test
    25 go
    26 -----------------------------------------------------------------
    27 
    28 /*系统存储过程*/
    29 
    30 EXEC sp_who   --显示当前用户、会话和进程的信息
    31 EXEC sp_who sa   
    32 
    33 EXEC sp_helpdb  test    --显示指定数据库的信息 
    34 
    35 EXEC sp_monitor   --显示sql server的统计信息,
    36                   --比如上次运行sp_monitor的时间,
    37                   --当前运行sp_monitor的时间,cpu处理sql server工作所用的秒数等信息
    38 
    39 EXEC sp_help   --显示数据库对象信息
    40 EXEC sp_help student  --显示存储过程的参数及其数据类型
    41 
    42 exec sp_helptext student   --显示存储过程的定义
    43 
    44 exec sp_depends sc  --显示和存储过程相关的数据库对象 
    45 
    46 exec sp_stored_procedures  --显示当前数据库中的存储过程列表
    47 go
     
    创建存储过程 

    CREATE PROC[EDURE ] procedure_name

        [ {@parameter data_type} [ = default]

        [OUTPUT] ] [,…n]

        [with {recompile|encryption|recompile,encryption}] [FOR REPLICATION]

       AS

        sql_statement […n ]

    其中:

    @parameter:过程中的参数。在该语句中可以声明一个或多个参数。用户必须在执行过程时提供每个所声明参数的值,使用@符号作为第一个字符来指定参数名称。
    data_type:参数的数据类型。
    Default:参数的默认值。
    OUTPUT:表明参数是返回参数。
    Recompile: 该过程在运行时编译
     
    例如:
     1 /*普通存储过程*/
     2 
     3 /*例: 创建存储过程maxgrade,输出所有学生的最高分:*/
     4 create procedure maxgrade
     5 as 
     6 begin
     7   set nocount on  -- 使返回的结果中不包含受Transact-SQL语句影响的行数的信息。   
     8   select max(grade) as '最高分' from sc
     9 end
    10 go
    11 
    12 select * from sc
    13 exec  maxgrade
    14 go
    15 
    16 -- drop proc maxgrade
    17 -----------------------------------------------------------------------------------
    18 
    19 use test
    20 
    21 /*临时存储过程*/
    22 /*创建临时存储过程#s_g,检索所有学生的成绩记录,包括学号、姓名、所选课程号和成绩:*/
    23 
    24 create procedure #s_g
    25 as
    26     select student.sno,student.sname,sc.cno,sc.grade
    27     from student,sc
    28     where student.sno=sc.sno 
    29     order by student.sno
    30 go
    31 
    32 exec #s_g        --执行该存储过程:
    33 go
    34 ----------------------------------------------------------------------------------------------
    35 
    36 /*加密存储过程*/
    37 /*创建加密存储过程s_a,查询学生的平均年龄*/
    38 
    39 create procedure s_a
    40 with encryption
    41 as
    42     select avg(sage) from student
    43 
    44 go
    45 
    46 exec s_a       
    47 exec sp_helptext s_a
    48 exec sp_helptext maxgrade
    49 go
     
    执行存储过程 
     
    执行存储过程使用EXECUTE语句,其格式为:

    [ [ EXEC [ UTE ] ]

    { [ @return_status =]

    { procedure_name| @procedure_name_var}

    [ [ @parameter = ]

    { value|@variable[OUTPUT] | [DEFAULT]}]

    [ , …n ]

    [with recompile]}

    各个参数的含义:
    @return_status  保存存储过程的返回状态
    procedure_name 调用的存储过程的名称
    @parameter 过程参数
    Value 过程参数的值
    @variable 用来保存参数或返回参数的变量
    OUTPUT 指定存储过程必须返回的一个参数
    DEFAULT 默认参数值
     
     
    存储过程的参数
     
    1. 使用参数

    带参数的存储过程的一般格式如下:

    CREATE PROCEDURE 存储过程名( 参数列表 )

    AS SQL语句

    例如:

     1 /*带参数的存储过程*/
     2 /*创建存储过程insert_sc向表中插入一条记录*/
     3 
     4 CREATE PROCEDURE insert_sc(@sno int,@cno int,@grade int)
     5 AS 
     6 INSERT INTO sc(sno,cno,grade) VALUES (@sno,@cno,@grade)
     7 GO
     8 
     9 
    10 
    11 declare @a int   --保存存储过程返回的状态;
    12 exec @a=insert_sc 1,3,100  --带参数的存储过程的执行方式一
    13 select @a
    14 select * from sc
    15 
    16 --
    17 exec insert_sc @sno=2,@cno=3,@grade=99   --带参数的存储过程的执行方式二
    18 select * from sc
    19 
    20 drop proc insert_sc
    21 go
    2. 使用默认参数
     
    在设计存储过程时,可以为参数提供一个默认值,默认值必须为常量或者NULL。其一般格式如下:

    CREATE PROCEDURE 存储过程名( 参数1=默认值1, 参数2=默认值2,… )

    AS SQL语句

    在调用存储过程时,如果不指定对应的实参值,则自动用对应的默认值代替。
     
    例如:
     1 /*在存储过程中使用默认值*/
     2 
     3 create proc select_student(@sno int=1)
     4 as 
     5 select student.sno,student.sname,sc.cno,sc.grade
     6     from student,sc
     7     where student.sno=@sno and student.sno=sc.sno
     8 go
     9 
    10 exec select_student   --不指定参数调用,则使用默认参数值1
    11 exec select_student 2  --指定参数调用
    12 
    13 drop proc select_student
    14 go
     
     
    3. 使用返回参数

        在创建存储过程时,可以定义返回参数。在执行存储过程时,可以将结果给返回参数。返回参数用OUTPUT进行说明。

    例如:

     1 /*例:创建一个存储过程average,它返回两个参数@st_name和@st_avg,
     2 分别代表了姓名和平均成绩,即查询指定学号的学生的姓名和平均成绩*/
     3 
     4 create procedure average
     5     (@st_sno int,     
     6      @st_sname char(10) output,
     7      @st_avg float output)
     8 as 
     9     select @st_sname=student.sname, @st_avg=avg(sc.grade)
    10     from student,sc
    11     where student.sno=sc.sno and student.sno=@st_sno
    12     group by student.sname
    13 go
    14 
    15 --执行以上存储过程average,查询学号为“1”的学生姓名和平均分:
    16 declare @st_sname char(10), @st_avg float
    17 exec average 2,@st_sname output, @st_avg output
    18 select @st_sname as '姓名', @st_avg  as '平均分' --或select '平均分'=@st_avg
    19 go
    20 
    21 --drop proc average
    22 go
    4. 存储过程的返回值
     
    存储过程在执行后都会返回一个整型值(称为“返回代码”),指示存储过程的执行状态。
    如果执行成功,返回0;否则返回-1~-99之间的数值(例如-1表示找不到对象,-2表示数据类型错误,-5表示语法错误等)。
    也可以使用RETURN语句指定一个返回值。
     
    例如:
     1 /*存储过程在执行后都会返回一个整型值,如成功执行返回0;如失败则返回-1至-99*/
     2 /*也可以使用return语句来指定一个返回值*/
     3 
     4 
     5 /*例: 创建存储过程maxgrade,输出所有学生的最高分:*/
     6 create procedure maxgrade1
     7 as 
     8 begin
     9   set nocount on  -- 使返回的结果中不包含受Transact-SQL语句影响的行数的信息。   
    10   select max(grade) as '最高分' from sc
    11 end
    12 go
    13 
    14 
    15 declare @ret_int int   --保存返回值
    16 exec @ret_int=maxgrade1  --执行该存储过程
    17 print @ret_int
    18 
    19 drop proc maxgrade1
     
    在调用存储过程时的两种传递参数的方式:
    方式一:

        EXEC 存储过程名 实参列表

    方式二:

         EXEC 存储过程名 参数1=值1,参数2=值2,…

    例如:

     1 /*例: 创建存储过程test_ret根据输入的参数来判断返回值:*/
     2 create proc test_ret(@input_int int=0)
     3 as 
     4 begin
     5     if @input_int=0
     6         return 0   --输入的参数等于0,则返回0
     7     if @input_int>0
     8         return 1000    --输入的参数大于0,则返回1000
     9     if @input_int<0
    10         return -1000    --输入的参数大于0,则返回-1000
    11 end
    12 
    13 declare @ret_int int   --保存返回值
    14 exec @ret_int=test_ret 1   --执行该存储过程
    15 print '返回值'
    16 print '--------'
    17 print @ret_int
    18 
    19 
    20 declare @ret_int int   --保存返回值
    21 exec @ret_int=test_ret 0
    22 print @ret_int
    23 
    24 
    25 declare @ret_int int   --保存返回值
    26 exec @ret_int=test_ret -1
    27 print @ret_int
    28 
    29 drop proc test_ret

    查看、修改和删除存储过程

     
    使用SQL Server管理控制器查看或修改存储过程
    使用sp_helptext存储过程来查看存储过程的定义信息
    使用SQL Server管理控制器删除存储过程
    使用DROP PROCEDURE删除存储过程
     
    例如:
     1 /*修改存储过程*/
     2 /*修改存储过程s_a,查询学生的最大年龄,不加密了!*/
     3 
     4 alter procedure s_a
     5 as
     6     select max(sage) from student
     7 go
     8 
     9 exec s_a       
    10 exec sp_helptext s_a
    11 go
    12 ----------------------------------------------------------------------------------------------
    13 
    14 /*删除存储过程*/
    15 
    16 drop procedure s_a
     1 /*例:编写一个程序,先创建一个存储过程studproc,输出95031班的所有学生,
     2 利用sysobjects和syscommnts两个系统表输出该存储过程的id和text列。
     3 然后利用ALTER PROCEDURE语句修改该存储过程,将其改为加密方式,最后在输出该存储过程的
     4 id和text列。*/
     5 
     6 use school
     7 go
     8 
     9 create procedure studproc
    10 as 
    11     select * from student where sclass='95031'
    12 go
    13 
    14 --通过以下语句输出studproc存储过程的id和text列
    15 select sysobjects.id,syscomments.text
    16     from sysobjects,syscomments
    17     where sysobjects.name='studproc' and sysobjects.type='p' and sysobjects.id=syscomments.id
    18 
    19 --修改该存储过程:
    20 alter procedure studproc
    21 with encryption 
    22 as 
    23     select * from student where sclass='95031'
    24 go
    25 
    26 --再通过以下语句输出studproc存储过程的id和text列
    27 select sysobjects.id,syscomments.text
    28     from sysobjects,syscomments
    29     where sysobjects.name='studproc' and sysobjects.type='p' and sysobjects.id=syscomments.id
    30 
    31 ---------------------------------
    32 
    33 /*例: 更名用户存储过程studproc1为studproc*/
    34 
    35 use school
    36 go
    37 
    38 exec sp_rename studproc,studproc1
    39 
    40 ---------------------------------
    41 
    42 /*使用DROP PROCEDURE语句删除用户存储过程stud_degree和stud1_degree。*/
    43 
    44 USE school
    45 GO
    46 DROP PROCEDURE stud_degree,stud1_degree
    47 GO

    存储过程示例:

     1 /*示例:
     2 
     3 下面的存储过程从四个表的联接中返回所有作者(提供了姓名)、
     4 出版的书籍以及出版社。该存储过程不使用任何参数。*/
     5 
     6 CREATE PROCEDURE au_info_all
     7 AS
     8 SELECT au_lname, au_fname, title, pub_name
     9    FROM authors a INNER JOIN titleauthor ta
    10       ON a.au_id = ta.au_id INNER JOIN titles t
    11       ON t.title_id = ta.title_id INNER JOIN publishers p
    12       ON t.pub_id = p.pub_id
    13 GO
    14 /*该存储过程可以通过以下方法执行:*/
    15 
    16 EXECUTE au_info_all
    17 -- Or
    18 EXEC au_info_all
    19 
    20 /*如果该过程是批处理中的第一条语句,则可使用:*/
    21 
    22 au_info_all
    23 
    24 ---------------------------------
    25 /*下面的存储过程从四个表的联接中只返回指定的作者(提供了姓名)、出版的书籍以及出版社。
    26 该存储过程接受与传递的参数精确匹配的值。*/
    27 
    28 USE pubs
    29 IF EXISTS (SELECT name FROM sysobjects 
    30          WHERE name = 'au_info' AND type = 'P')
    31    DROP PROCEDURE au_info
    32 GO
    33 USE pubs
    34 GO
    35 CREATE PROCEDURE au_info 
    36    @lastname varchar(40), 
    37    @firstname varchar(20) 
    38 AS 
    39 SELECT au_lname, au_fname, title, pub_name
    40    FROM authors a INNER JOIN titleauthor ta
    41       ON a.au_id = ta.au_id INNER JOIN titles t
    42       ON t.title_id = ta.title_id INNER JOIN publishers p
    43       ON t.pub_id = p.pub_id
    44    WHERE  au_fname = @firstname
    45       AND au_lname = @lastname
    46 GO
    47 
    48 /*au_info 存储过程可以通过以下方法执行:*/
    49 
    50 EXECUTE au_info 'Dull', 'Ann'
    51 -- Or
    52 EXECUTE au_info @lastname = 'Dull', @firstname = 'Ann'
    53 -- Or
    54 EXECUTE au_info @firstname = 'Ann', @lastname = 'Dull'
    55 -- Or
  • 相关阅读:
    iOS开发之友盟分享的使用
    iOS开发之AFNetworking开源库的使用
    iOS开发之网络基础知识
    iOS开发之Block
    iOS开发之数据库FMDB
    iOS开发常用的网站
    iOS开发之下拉刷新和上拉加载更多
    iOS开发之XML解析
    iOS之网络数据下载和JSON解析
    Linux 部署项目经验总结
  • 原文地址:https://www.cnblogs.com/z941030/p/5243827.html
Copyright © 2011-2022 走看看