数据库存储过程的示例分析

53次阅读
没有评论

共计 11601 个字符,预计需要花费 30 分钟才能阅读完成。

自动写代码机器人,免费开通

这篇文章给大家分享的是有关数据库存储过程的示例分析的内容。丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,一起跟随丸趣 TV 小编过来看看吧。

/*
存储过程可以看作是在数据库中的存储 t -sql 脚本
为什么使用存储过程
1、增加性能   本地存储发送的内容少、调用快、预编译、高速缓存
  一般语句的执行:检查权限、检查语法,建立执行计划处理语句的要求
  存储过程:创建时已经检查了语法;第一次执行的时候执行计划被创建,被编译;  再次执行时不需要重检查语法、不需要重编译、根据已经缓存的计划来决定是否需要重创建执行计划
2、增强安全   加密、分离(权限设置,用户只需要有执行存储过程的权限,不需要有访问存储过程所使用的对象的权限) 
3、在 transact-sql 中使用非数据库技术  dll
4、编程模式——使用外部编程语言调用
 1)input
 2)output
 3)feedback  状态代码或描述性的文本
 4)模块化、可重用、可调用其他存储过程
 5)隐藏程序逻辑,便于编程
 6)可以调用动态连接库(外接的程序)基本原则:越简单越好   单一任务
1、系统存储过程  
  存在于 master 数据库,一般以 sp_开头
  提供对系统表格数据调用、数据库管理功能、安全管理功能的支持
 -- 表格授权
 use pubs
 go
 execute sp_table_privileges stores
 -- 显示 kylin\administrator 的所有进程
 execute sp_who @loginame= W2K3SERVER\Administrator 
 -- 报告有关孤立的  microsoft windows nt  用户和组的信息,这些用户和组已不在  windows nt  环境中,但仍在  microsoft sql server 系统表中拥有项。 execute sp_validatelogins
2、本地存储过程   用户创建的解决特定问题的
3、临时存储过程   存储于 tempdb
  创建、调用时的数据库   使用范围   生存周期  
 #local  不限数据库   创建时的连接有效   从创建时开始,当创建的连接中断时消失
 ##global  不限数据库   所有连接   从创建时开始,当创建的连接中断时消失
  直接创建在 tempdb 的存储过程  tempdb  所有连接   从创建时开始,当数据库服务器服务停止时消失
 create proc #local
 as
 select  #local 
 go
 exec #local
 go
 create proc ##global
 as
 select  ##global 
 go
 exec ##global
 go
 use tempdb
 go
 create procedure directtemp
 as
 select * from [pubs].[dbo].[authors]
 go
 use northwind
 go
 exec tempdb.dbo.directtemp
4、扩展存储过程  c++ xp
 xp_sendmail 既是系统存储过程,也是扩展存储过程
  使用 objectproperty 来判断是否是扩展存储过程
 use master
 -- 扩展存储过程
 select objectproperty(object_id( sp_prepare),  isextendedproc )
 -- 非扩展存储过程
 select objectproperty(object_id( xp_logininfo),  isextendedproc )
5、远程存储过程
  目前版本中只是为了向后兼容,已被分布式查询替代

select * from syscomments  where id = object_id(custorderhist) select name,text from sysobjects inner join syscomments  on sysobjects.id = syscomments.id where sysobjects.name =  custorderhist sp_helptext sp_helptext use northwind exec sp_help custorderhist exec sp_helptext custorderhist exec sp_depends custorderhist exec sp_stored_procedures  custorderhist  
-- -- -- select top 1 * from products -- -- -- select top 1 * from orders -- -- -- select top 1 * from [order details] /*1、和视图比较 */ alter proc sp_qry_salesdetails select a.productid as  商品编号,a.productname as  商品名称,b.unitprice as  数量,b.quantity as  价格, b.unitprice*b.quantity as  金额,c.requireddate as  销售时间 from [order details] as b join products as a on b.productid=a.productid join orders as c on b.orderid=c.orderid print  测试 execute sp_qry_salesdetails -- 递归算法 -- 视图   存储过程   函数 alter view v_qry_salesdetails select a.productid as  商品编号,a.productname as  商品名称,b.unitprice as  数量,b.quantity as  价格, b.unitprice*b.quantity as  金额,c.requireddate as  销售时间 from [order details] as b join products as a on b.productid=a.productid join orders as c on b.orderid=c.orderid print  测试 select * from v_qry_salesdetails  默认情况下第一次执行时的执行计划被保存,以后执行时都是用这个执行计划,直到服务器重启或存储过程使用的表格变化时 当存储过程变化时,如:参数变化,需要重新编译、制定新的执行计划 当每次调用存储过程时强制重新编译的方法:1、创建时指定  with recompile  2、sp_recompile  create procedure sp1 as  select * from customers exec sp1 alter procedure sp1 as  select * from customers alter procedure sp1 with recompile as  select * from customers sp_recompile sp1 -- 加密存储过程  with encryption  select objectproperty(object_id( sp_qry_salesdetails),  isencrypted ) 删除存储过程 drop proc  use northwind create proc dbo.sp_dropproc select  northwind.dbo.sp_dropproc exec northwind.dbo.sp_dropproc use master create proc dbo.sp_dropproc select  master.dbo.sp_dropproc exec master.dbo.sp_dropproc use northwind drop proc sp_dropproc exec sp_dropproc exec master.dbo.sp_dropproc 提供输入参数  input create proc qry_salesdetails @y int,@m int --varchar(10) select a.productid as  商品编号,a.productname as  商品名称,b.unitprice as  数量,b.quantity as  价格,b.unitprice*b.quantity as  金额,c.requireddate as  销售时间 from [order details] as b join products as a on b.productid=a.productid join orders as c on b.orderid=c.orderid --where convert(varchar(2),month(c.requireddate)) = @m where year(c.requireddate) = @y and month(c.requireddate) = @m go  exec qry_salesdetails 1996,9 exec qry_salesdetails 9,1996 exec qry_salesdetails @m=9,@y=1996 exec qry_salesdetails @y=1996,@m=9 northwind  数据库 orders order details  表格  * 根据指定用户 ID 显示此用户在 1996-07-01 到 1997-07-01 之间的订货记录   要求存储过程文本加密  
-- drop proc qry_showorders  create proc qry_showorders @custid nchar(5) with encryption -- 加密 if @custid is null -- begin -- print  提供了不正确的参数 -- return -- end select *  from orders od inner join [order details] oddt on od.orderid = oddt.orderid where shippeddate  = 1996-07-01  and shippeddate  = 1997-07-01 and od.customerid = @custid -- 调用、检验刚刚创建的存储过程 exec qry_showorders @custid =  vinet exec qry_showorders null -- 检查是否已经被加密 exec sp_helptext qry_showorders 返回值  output , 一个返回值变量一次只能有一个返回的值 create proc testoutput @a varchar(10) output select @a = 100 declare @b varchar(10) --exec testoutput @b output exec testoutput @a=@b output select @b --error create proc sum_money @count money, @unitprice money as  select @count*@unitprice declare @sum_temp money ,@sum_temp2 money set @sum_temp2 = exec sum_money @count= 1.1,@unitprice = 2.2  create proc sum_money @count money, @unitprice money ,@sum money output as  set @sum = @count*@unitprice declare @sum_temp money ,@sum_temp2 money exec sum_money @count= 1.1,@unitprice = 2.2,@sum = @sum_temp output set @sum_temp2= @sum_temp*100 select @sum_temp2
create proc test_output @in nvarchar(100),@out nvarchar(100) output print  i m @in   + @in set @out = @in print  i m @out  +@out declare @i nvarchar(100),@o nvarchar(100) set @i =  让我们一起来测试 exec test_output @in = @i,@out = @o output select @o return  语句和错误处理 --return  主要用来进行错误处理 create proc testreturn @a int as  if @a 0 begin  return(-1) end  else if @a = 0 begin  return(0) end  else  begin  return(1) end  declare @rtn int exec @rtn = testreturn @a=-100 select @rtn  @@error select @@error select  a +1 select @@error
select error, description from master.dbo.sysmessages where error = 245 create proc testerror as  select  a +1 exec testerror create proc testerror declare @e int,@a int ,@b int set @e = 0 set @a = 1 set @b = 0 select @a/@b if @@error 0 begin  print  有错误  set @e = @@error  return @e declare @er int exec @er = testerror select @er  @@rowcount select @@rowcount select * from customers select @@rowcount null  值 create proc testreturn @a int as  if @a is null begin  return(100) else if @a 0 begin  return(-1) end  else if @a = 0 begin  return(0) end  else  begin  return(1) end 
/*************************************************************************************************************************** ***************************************************************************************************************************/ 关于 sp_的命名 use master create sp_test select  现在是 master 数据库 use northwind create sp_test select  现在是 northwind 数据库 exec sp_test exec master.dbo.sp_test drop sp_test  create proc sp1_test as  select  这是 master use northwind create proc sp1_test as  select  这是 northwind exec sp1_test drop proc sp1_test 命名延迟解决方案:创建存储过程时,应用的对象可以不存在,建议存储过程及引用的对象所有者都设置为 dbo -- 按契约编程 use northwind create proc testdelay select * from tbldelay exec testdelay 在创建存储过程时可以逻辑上形成组,以便作为同一个管理单元并在一个程序中使用 create proc groupedproc;1  select  groupedproc;1  create proc groupedproc;2 select  groupedproc;2  sp_helptext groupedproc exec groupedproc;1 exec groupedproc;2 exec groupedproc drop proc groupedproc 存储过程嵌套,最多 32 层 */  create proc a  select  a create proc b select  b exec a  exec b 使用默认值 -- -- drop proc testdefault create proc testdefault @a int,@b int=2 select @a,@b exec testdefault 1 exec testdefault @a=1 exec testdefault 1,100 在服务器启动时自动运行的存储过程 要求:所有者是 dbo,在 master 数据库中 use northwind create table start dt datetime use master create proc autostart insert into northwind.dbo.start values(getdate()) -- 设置为自动运行 execute sp_procoption @procname = autostart, @optionname = startup, @optionvalue = true use master -- 判断是否自动运行 select objectproperty(object_id( autostart),  execisstartup ) select * from northwind.dbo.start -- 停止自动运行 execute sp_procoption @procname = autostart, @optionname = startup, @optionvalue = false execute sp_configure @configname =  scan for startup procs , @configvalue = 0 reconfigure
-- -- --  -- -- -- ------msg 15281, level 16, state 1, procedure xp_cmdshell, line 1 -- -- -- ------sql server blocked access to procedure  sys.xp_cmdshell  of component  xp_cmdshell  because this component is turned off as part of the security configuration for this server. a system administrator can enable the use of  xp_cmdshell  by using sp_configure. for more information about enabling  xp_cmdshell , see  surface area configuration  in sql server books online.  ---exec xp_cmdshell  dir *.exe -- -- --  -- -- -- exec xp_cmdshell tree -- -- -- 
  练习:向 northwind 数据库中的 customers  表格插入记录的存储过程   名字 insertcust select  insert update delete create proc insertcust @custid nchar(5),  @cmpnm nvarchar(40),  @cntnm nvarchar(30),  @cntttl nvarchar(30),  @addr nvarchar(60),   @city nvarchar(15),  @rg nvarchar(15),  @pscd nvarchar(10),  @cntry nvarchar(15),  @phone nvarchar(24),  @fax nvarchar(24) as  -- 业务逻辑 insert into customers(customerid,companyname,contactname,contacttitle, address,city,region,postalcode,country,phone,fax) values(@custid,@cmpnm,@cntnm,@cntttl, @addr,@city,@rg,@pscd,@cntry,@phone,@fax) exec insertcust @custid= abcd ,@cmpnm= abc company ,@cntnm= anyone ,@cntttl= mr. ,@addr= anywhere ,  @city= shanghai ,@rg= huangpu ,@pscd= 200000 ,@cntry= chian ,@phone= 021-88888888 ,@fax= 021-66666666 -- 简单实现 create proc createcustid @id nchar(5) output as   -- 自动产生客户 ID create proc insertcust   @cmpnm nvarchar(40),  @cntnm nvarchar(30),  @cntttl nvarchar(30),  @addr nvarchar(60),   @city nvarchar(15),  @rg nvarchar(15),  @pscd nvarchar(10),  @cntry nvarchar(15),  @phone nvarchar(24),  @fax nvarchar(24) as  declare @id nchar(t5) exec createcustid @id output insert into customers(customerid,companyname,contactname,contacttitle,address,city,region,postalcode,country,phone,fax) values(@id,@cmpnm,@cntnm,@cntttl,@addr,@city,@rg,@pscd,@cntry,@phone,@fax) 其他要考虑的因素:customerid  自动生成 如果重复怎么处理?  生成新 id?电话号码格式不正确如何处理? return ------------------------------------------------------------------------------------------------------------------------ set nocount off select  a -- -- --  set nocount on select  a 动态语句的使用——动态条件
create proc qry_salesdetails @no int = -1,@start char(10),@end char(10) select a.productid as  商品编号,a.productname as  商品名称,b.unitprice as  数量,b.quantity as  价格,b.unitprice*b.quantity as  金额,c.requireddate as  销售时间    from [order details] as b join products as a  on b.productid=a.productid  join orders as c  on b.orderid=c.orderid where a.productid= @no and c.requireddate =@end  and c.requireddate =@start exec qry_salesdetails 6, 1996-01-01 , 1997-01-01
alter proc qry_salesdetails @no int = -1,@start char(10),@end char(10) as  declare @sql varchar(4000) set @sql =  select a.productid as  商品编号,a.productname as  商品名称, b.unitprice as  数量,b.quantity as  价格,b.unitprice*b.quantity as  金额, c.requireddate as  销售时间    from [order details] as b join products as a  on b.productid=a.productid  join orders as c  on b.orderid=c.orderid where 1=1  if @no is not null  set @sql = @sql +   and a.productid =  +convert(varchar(10),@no) if @start is not null and @end is not null  set @sql = @sql +   and c.requireddate  =  + @start+  +   and c.requireddate  =  + @end+ --print @sql exec(@sql) print  go  exec qry_salesdetails @end=null,@start=null exec qry_salesdetails @no=35,@end=null,@start=null exec qry_salesdetails @no=null,@end= 1997-07-01 ,@start= 1996-07-01 exec qry_salesdetails @no=38,@end= 1997-07-01 ,@start= 1996-07-01 sp_stored_procedures qry_salesdetails
insert into #temp select a.productid as  商品编号,a.productname as  商品名称,  b.unitprice*b.quantity as  金额,c.requireddate as  销售时间,  month(c.requireddate) from [order details] as b join products as a on b.productid=a.productid join orders as c on b.orderid=c.orderid where year(c.requireddate) = 1996 insert into #temp(商品编号, 金额, 排序) select  月汇总 ,sum(金额),month(销售时间) from #temp group by year(销售时间),month(销售时间)   insert into #temp(商品编号, 金额, 排序) select  年汇总 ,sum(金额),12 from #temp where  销售时间  is not null select * from #temp order by  排序  , 商品名称  desc select * from #temp drop table tempdb..#temp

感谢各位的阅读!关于“数据库存储过程的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

向 AI 问一下细节

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-12-04发表,共计11601字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)