zoukankan      html  css  js  c++  java
  • sql server 存储过程使用游标记录

    sql server 存储过程使用游标记录--方便下次参考使用

    游标的组成:

    • 声明游标
    • 打卡游标
    • 从一个游标中查找信息
    • 关闭游标
    • 释放游标

    游标类型:

    • 静态游标
    • 动态游标
    • 只进游标
    • 键集驱动游标

    静态游标:静态游标的完整结果集在游标打开时建立在tempdb中。静态游标总是按照游标打开时的原样显示结果集。

    静态游标在滚动期间很少或根本监测不到变化,虽然在tempdb中存储了整个游标,但消耗的资源很少。尽管动态游标使用tempdb的程度最低,在滚动期间它能够监测到所有变化,单消耗的资源也更多。

    键集驱动游标介于二者之间,它能够监测到大部分的变化,但比动态游标消耗更少的资源。

    动态游标:与静态游标相对。当滚动游标时,动态游标反映结果集中所作的所有更改。结果集中的行数据值、顺序和成员在每次提取时都会改变。所有用户做的全部update、insert、delete语句均通过游标可见。

    只进游标:只进游标不支持滚动,它只支持游标从头到尾顺序提取。只在从数据库中提取出来后才能进行检索。对所有由当前用户发出或其他用户提交,并影响结果集中的行的insert、update、delete语句,其效果在这些行从游标中提取时是可见的。

    键集驱动游标:打开游标时,键集驱动游标中的成员和行顺序是固定的。键集驱动游标由一套被称为键集的唯一标识符(键)控制。键由以唯一方式在结果集中标识行的列构成。键集是游标打开时来自所有适合select语句的行中的一系列键值,键集驱动

    游标打开时建立在tempdb中。对非键集列中的数据值所做的更改(由游标所有者更改或其他用户提交)在用户滚动游标时是可见的,在游标外对数据库所做的插入在游标内是不可见的,除非关闭并重新打开游标。

    参考实例如下:

    USE [hhris]
    GO
    /****** Object:  StoredProcedure [dbo].[INIT_DICT_QUEUECODE]    Script Date: 2018-09-21 17:12:12 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    --if (exists (select * from sys.objects where name = 'INIT_DICT_QUEUECODE'))
        --drop proc INIT_DICT_QUEUECODE
    --go
    --create  procedure INIT_DICT_QUEUECODE
    -- =============================================
    -- Author:		<sunwugang>
    -- ALTER date: <2018-09-21>
    -- Description:	<添加参数维护>
    -- =============================================
    ALTER   procedure [dbo].[INIT_DICT_QUEUECODE]
    (
    	 @p_QUEUEID int,
    	 @p_QUEUENAME  varchar(100),
    	 @p_DEVICECOUNT int, 
    	 @p_CHECKDURATION int,
    	 @p_BEGINTIMEPART varchar(50),
    	 @p_ENDTIMEPART varchar(50),
    	 @p_CODECOUNT int,
    	 @p_QUEUESIGN varchar(50),
    	 @p_ADDRESS varchar(50),
    	 @p_ofdepart varchar(30),
    	 @p_PMBEGINTIME varchar(50),
    	 @p_PMENDTIME varchar(50),
    	 @p_CodeCoefficient varchar(50),
    	 @p_TIMEPART varchar(50),
    	 @p_PARAMTYPE  varchar(50),
    	 @p_CALLTYPE varchar(50),
    	 @p_result int output
    )
    as
    insert into QS_PARAM (QUEUEID, QUEUENAME, DEVICECOUNT, CHECKDURATION, BEGINTIMEPART, ENDTIMEPART, CODECOUNT,QUEUESIGN,ADDRESS,ofdepart,PMBEGINTIME, PMENDTIME, CodeCoefficient, TIMEPART,PARAMTYPE,CALLTYPE)
    values(@p_QUEUEID, @p_QUEUENAME, @p_DEVICECOUNT, @p_CHECKDURATION, @p_BEGINTIMEPART, @p_ENDTIMEPART, @p_CODECOUNT,@p_QUEUESIGN,@p_ADDRESS,@p_ofdepart,@p_PMBEGINTIME, @p_PMENDTIME, @p_CodeCoefficient, @p_TIMEPART,@p_PARAMTYPE,@p_CALLTYPE)
    declare 
    	@loopNum int,--循环次数
    	 @codeNum int,--号源编号
    	 @codeFirstAm int,
    	 @codeFirstPm int
    DECLARE  paramDetails cursor 
    for 
    	select queuename,paramtype,begintimepart,endtimepart,ofdepart,calltype,codecount from qs_param  a 
    	where a.queueid=@p_QUEUEID and a.paramtype=@p_PARAMTYPE order by convert(float,endtimepart)
     begin  try
    	 set @loopNum=1
    	 set @codeNum=1
    	 set @codeFirstAm=0--未进行初始化
    	 set @codeFirstPm=0--未进行初始化
    	--删除号源字典
    	 delete from dict_queuecode  where queuename=@p_QUEUENAME and codeparamtype=@p_PARAMTYPE and ofdepart=@p_ofdepart
    begin tran --当前事务点,rollback、commit都从这里开始    
    	DECLARE
    					 @v_QUEUEID int,
    					 @v_QUEUENAME  varchar(100),
    					 @v_DEVICECOUNT int, 
    					 @v_CHECKDURATION int,
    					 @v_BEGINTIMEPART varchar(50),
    					 @v_ENDTIMEPART varchar(50),
    					 @v_CODECOUNT int,
    					 @v_QUEUESIGN varchar(50),
    					 @v_ADDRESS varchar(50),
    					 @v_ofdepart varchar(30),
    					 @v_PMBEGINTIME varchar(50),
    					 @v_PMENDTIME varchar(50),
    					 @v_CodeCoefficient varchar(50),
    					 @v_TIMEPART varchar(50),
    					 @v_PARAMTYPE  varchar(50),
    					 @v_CALLTYPE varchar(50)
     open paramDetails
     fetch next from paramDetails into @v_queuename,@v_paramtype,@v_begintimepart,@v_endtimepart,@v_ofdepart,@v_calltype,@v_codecount
    		WHILE @@FETCH_STATUS =0
    		 begin
    					--循环获取qs_param表中维护的某个时间段
    					set @loopNum=1
    					 while @loopNum <= @v_codecount 
    							 begin
    								--上午
    								  if @codeFirstAm=0 and @v_calltype='上午' 
    									  begin
    											set @codeNum=1
    											set @codeFirstAm=1
    										end
    								--下午
    								  if @codeFirstPm=0 and @v_calltype='下午' 
    									  begin
    											set @codeNum=1
    											set @codeFirstPm=1
    										end
    								  --添加号源信息
    									insert into DICT_QUEUECODE  (queuename,codeparamtype,codevalue,timepart,hintinfo,OFDEPART,calltype,queueid)
    									values (@v_queuename,@v_paramtype,@codeNum,@v_begintimepart+'~'+@v_endtimepart,'',@v_ofdepart,@v_calltype,@p_QUEUEID)
    								  --重新赋值
    									 set @loopNum=@loopNum+1
    									 set @codeNum=@codeNum+1
    							end
    		fetch next from paramDetails into @v_queuename,@v_paramtype,@v_begintimepart,@v_endtimepart,@v_ofdepart,@v_calltype,@v_codecount
    		end
    		close paramDetails
    		DEALLOCATE  paramDetails
    		set @p_result=1
    		 commit    
    end try
    begin catch
          set @p_result=-1
          rollback    
    end catch
    

      

      

      实例二

    USE [MES30]
    GO
    /****** Object:  StoredProcedure [dbo].[sp_WM_DeliveryCommit]    Script Date: 2018/9/20 16:21:13 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    -- =============================================
    -- Author:		
    -- ALTER date: <2017-06-13>
    -- Description:	<发货单提交>
    -- =============================================
    ALTER procedure  [dbo].[sp_WM_DeliveryCommit] 
    (
    	@DeliveryCode NVARCHAR(50)
    ) 
    AS 
    BEGIN
    	SET NOCOUNT ON;
    	DECLARE @ERROR_MESSAGE NVARCHAR(4000);
    	DECLARE @Flag NVARCHAR(50)
    	SET @Flag='0';
        BEGIN TRY
    		BEGIN TRAN;
    			DECLARE DeliveryCursor CURSOR    
    			FOR SELECT MatCode,DeliveryQty FROM t_WM_DeliveryDtl WHERE  _DeliveryCode=@DeliveryCode
    
    			OPEN DeliveryCursor
    
    			DECLARE @MatCode nvarchar(50),@DeliveryQty decimal(22,6)
    			FETCH NEXT FROM  DeliveryCursor INTO @MatCode,@DeliveryQty
    			WHILE @@FETCH_STATUS =0
    			BEGIN
    				DECLARE @tmpDeliveryQty decimal(22,6),@tmpRequireQty decimal(22,6),@tmpReturnQty decimal(22,6)
    				DECLARE @tmpStockQty decimal(22,6),@tmpQty decimal(22,6)
    				SELECT @tmpDeliveryQty=SUM(isnull(DeliveryQty,0)) FROM t_WM_DeliveryDtl,t_WM_Delivery 
    				WHERE DeliveryCode=_DeliveryCode and (DeliverySts=2 OR DeliverySts=3) and MatCode=@MatCode
    				SELECT @tmpRequireQty=SUM(isnull(RequireQty,0)) FROM t_WM_RequireDtl,t_WM_Require 
    				WHERE RequireCode=_RequireCode and (RequireSts=2 OR RequireSts=3) and MatCode=@MatCode
    				SELECT @tmpRequireQty=SUM(isnull(ReOutQty,0)) FROM t_WM_ReturnOutDtl,t_WM_ReturnOut
    				WHERE ReOutCode=_ReOutCode and (ReOutSts=2 OR ReOutSts=3) and MatCode=@MatCode
    				SELECT @tmpStockQty=SUM(isnull(ValidQty,0)) FROM t_WM_InDtl,t_WM_In
    				WHERE InCode=_InCode and MatCode=@MatCode
    				SET @tmpQty=isnull(@tmpStockQty,0)-isnull(@tmpDeliveryQty,0)-isnull(@tmpRequireQty,0)-isnull(@tmpReturnQty,0)-isnull(@DeliveryQty,0)
    				if(@tmpQty<0)
    				BEGIN
    					SET @Flag=@MatCode;
    					BREAK;;
    				END
    				FETCH NEXT FROM  DeliveryCursor INTO @MatCode,@DeliveryQty
    			END    
    
    			CLOSE DeliveryCursor
    			DEALLOCATE DeliveryCursor
    
    			if @Flag='0'
    				UPDATE t_WM_Delivery SET DeliverySts=2 WHERE DeliveryCode=@DeliveryCode
    
    		COMMIT TRAN
    	    SELECT @Flag;
        END TRY
        BEGIN CATCH	
    		SELECT  @ERROR_MESSAGE = ERROR_MESSAGE();
    		RAISERROR (@ERROR_MESSAGE , 16, 1);
    		SELECT -1;
        END CATCH
    	
    END
    

    实例三(该实例来自网络):

    ---游标循环遍历--
    begin
        declare @a int,@error int    
        declare @temp varchar(50)
        set @a=1
        set @error=0
        begin tran  --申明事务
        --申明游标为Uid
        declare order_cursor cursor 
        for (select [Uid] from Student)
        --打开游标--
        open order_cursor
        --开始循环游标变量--
        fetch next from order_cursor into @temp
        while @@FETCH_STATUS = 0    --返回被 FETCH语句执行的最后游标的状态--
            begin            
                update Student set Age=20+@a,demo=@a where Uid=@temp
                set @a=@a+1
                set @error= @error + @@ERROR   --记录每次运行sql后是否正确,0正确
                fetch next from order_cursor into @temp   --转到下一个游标
            end    
        if @error=0
        begin
            commit tran   --提交事务
        end
        else
        begin
            rollback tran --回滚事务
        end
        close order_cursor  --关闭游标
        deallocate order_cursor   --释放游标
    end
    

      

  • 相关阅读:
    java如何实现以数据流的形式下载压缩包到本地?
    在用easyui中做CRUD功能时,当删除一行或多行数据后再点击修改会提示你选中了多行,如何解决这个bug了?
    windows中当你的键盘无法使用时我们可以用另一种方法哦
    Idea中如何将web项目打包成war包并放到tomcat中启动
    [CSS3] Use media query to split css files and Dark mode (prefers-color-scheme: dark)
    [PWA] Storage information for PWA application
    [HTML5] Native lazy-loading for the web
    [Dynamic Programming] 198. House Robber
    [Javascript] Sort by multi factors
    [Javascript] Keyword 'in' to check prop exists on Object
  • 原文地址:https://www.cnblogs.com/YYkun/p/9685765.html
Copyright © 2011-2022 走看看