存儲過程學習(里面包含游標,事務,以及如何拋出異常等)


USE [JGB_DB]
GO
/****** 對象:  StoredProcedure [dbo].[P_CREATE_DATA_BY_EXCEL]    腳本日期: 08/13/2013 09:01:03 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[P_CREATE_DATA_BY_EXCEL] 
    -- Add the parameters for the stored procedure here
    @GUID_VALUE UNIQUEIDENTIFIER ,
    @RESULTMSG VARCHAR(1000) OUTPUT ,    --錯誤消息
    @RESULT BIT OUTPUT     --返回消息  1正確,0錯誤
AS 
    BEGIN
        DECLARE @BLOCKNAME VARCHAR(20) ,
            @ERROMESSAGE VARCHAR(20) ,
            @BLOCKID BIGINT ,
            @PROJ_ID BIGINT ,
            @PROJ_NAME VARCHAR(100) ,
            @I INT ,
            @G_NAME VARCHAR(400) ,
            @ERR_CODE VARCHAR(200)
        
        BEGIN TRY
            BEGIN TRANSACTION
            DECLARE CR_TOTAL CURSOR
            FOR
                SELECT  DISTINCT
                        BLOCK_NAME ,
                        G_NAME ,
                        PROJ_NAME
                FROM    dbo.T_INPOUR_DATA
                WHERE   GUID_VALUE = @GUID_VALUE
            OPEN CR_TOTAL
            FETCH NEXT FROM CR_TOTAL INTO @BLOCKNAME, @G_NAME, @PROJ_NAME
            WHILE ( @@FETCH_STATUS = 0 ) 
                BEGIN
                    SELECT  @PROJ_ID = PROJ_ID
                    FROM    dbo.T_PROJECT
                    WHERE   PROJ_NAME = @PROJ_NAME
            --獲取地塊ID
                    SET @ERR_CODE = '0.03'
                    SET @ERROMESSAGE = '樓盤獲取失敗'
                    DECLARE @GR_ID BIGINT
                    IF NOT EXISTS ( SELECT  *
                                    FROM    dbo.T_GROUND
                                    WHERE   G_NAME = @G_NAME AND PROJ_ID=@PROJ_ID ) 
                        BEGIN
                            INSERT  INTO dbo.T_GROUND
                                    ( PROJ_ID, G_NAME )
                            VALUES  ( @PROJ_ID, -- PROJ_ID - int
                                      @G_NAME )
                            SET @GR_ID = IDENT_CURRENT('T_GROUND')
                        END
                    ELSE 
                        SELECT  @GR_ID = GR_ID
                        FROM    dbo.T_GROUND
                        WHERE   G_NAME = @G_NAME
                                AND PROJ_ID = @PROJ_ID    
            --刪除舊數據
                    SET @ERR_CODE = '0.01'
                    SET @ERROMESSAGE = '原樓數據刪除失敗'
                    IF EXISTS ( SELECT  *
                                FROM    dbo.T_BLOCK
                                WHERE   BLOCK_NAME = @BLOCKNAME AND GR_ID=@GR_ID ) 
                        BEGIN
                            SELECT  @BLOCKID = BLOCK_ID
                            FROM    dbo.T_BLOCK
                            WHERE   BLOCK_NAME = @BLOCKNAME
                                    AND GR_ID = @GR_ID
                            DELETE  FROM dbo.T_ROOM
                            WHERE   BLOCK_ID = @BLOCKID
                            DELETE  FROM T_BLOCK_LAYER
                            WHERE   BLOCK_ID = @BLOCKID
                            DELETE  FROM T_BLOCK_BRANCH
                            WHERE   BLOCK_ID = @BLOCKID
                    
                            DELETE  FROM dbo.T_BLOCK
                            WHERE   BLOCK_ID = @BLOCKID
                        END
             
             --獲取樓的單元數、樓層數
                    SET @ERR_CODE = '0.02'
                    SET @ERROMESSAGE = '單元號存在不合法數據'
                    DECLARE @ROOMNO VARCHAR(20)
                    DECLARE @MAXLAYER INT ,
                        @LAYER INT
                    DECLARE @MAXBRACH INT ,
                        @BRACH INT
                    SET @MAXBRACH = 0
                    SET @MAXLAYER = 0
                    DECLARE CR_LAYER CURSOR
                    FOR
                        SELECT  ROOM_NO
                        FROM    dbo.T_INPOUR_DATA
                        WHERE   GUID_VALUE = @GUID_VALUE
                                AND PROJ_NAME = @PROJ_NAME
                                AND G_NAME = @G_NAME
                                AND BLOCK_NAME = @BLOCKNAME
                    OPEN CR_LAYER
                    FETCH NEXT FROM CR_LAYER INTO @ROOMNO
                    WHILE ( @@FETCH_STATUS = 0 ) 
                        BEGIN
                            IF LEN(@ROOMNO) < 4 
                                BEGIN
                                    SET @LAYER = CAST(SUBSTRING(@ROOMNO, 1, 1) AS INT)
                                    SET @BRACH = CAST(SUBSTRING(@ROOMNO, 2, 2) AS INT) 
                                    IF ( @LAYER > @MAXLAYER ) 
                                        SET @MAXLAYER = @LAYER
                                    IF ( @BRACH > @MAXBRACH ) 
                                        SET @MAXBRACH = @BRACH
                                END
                            ELSE 
                                BEGIN
                                    SET @LAYER = CAST(SUBSTRING(@ROOMNO, 1, 2) AS INT)
                                    SET @BRACH = CAST(SUBSTRING(@ROOMNO, 3, 2) AS INT)
                                    IF ( @LAYER > @MAXLAYER ) 
                                        SET @MAXLAYER = @LAYER
                                    IF ( @BRACH > @MAXBRACH ) 
                                        SET @MAXBRACH = @BRACH
                                END 
                               
                            FETCH NEXT FROM CR_LAYER INTO @ROOMNO
                        END
                    CLOSE CR_LAYER
                    DEALLOCATE CR_LAYER
            
             
            --生成樓
                    SET @ERR_CODE = '1.0'
                    SET @ERROMESSAGE = '生成樓失敗'
                    INSERT  INTO T_BLOCK
                            ( GR_ID, BLOCK_NAME )
                    VALUES  ( @GR_ID, @BLOCKNAME )
                       
                    SET @BLOCKID = IDENT_CURRENT('T_BLOCK') --SCOPE_IDENTITY()  
                       --生成樓層
                    SET @ERR_CODE = '1.2'
                       
                    SET @I = 1
                    WHILE @I <= @MAXLAYER 
                        BEGIN
                            INSERT  INTO T_BLOCK_LAYER
                                    ( BLOCK_ID, LAYER_NUM )
                            VALUES  ( @BLOCKID, @I )
                              
                            SET @I = @I + 1
                        END
                       --生成單元
                    SET @ERR_CODE = '1.3'
                    SET @ERROMESSAGE = '生成單元失敗'
                    SET @I = 1
                    WHILE @I <= @MAXBRACH 
                        BEGIN
                            INSERT  INTO T_BLOCK_BRANCH
                                    ( BLOCK_ID, BRANCH_NUM )
                            VALUES  ( @BLOCKID, @I )
                              
                            SET @I = @I + 1
                        END
            --生成房屋
                    SET @ERROMESSAGE = '生成房間失敗'
                    DECLARE @ROOM_NO VARCHAR(20) ,
                        @LAYER_NUM INT ,
                        @BRACH_NUM INT ,
                        @ROOM_SHAPE INT ,
                        @ROOM_SIZE NUMERIC(10, 2) ,
                        @ROOM_SIZE_INNER NUMERIC(10, 2) ,
                        @BLOCK_LAYER_ID BIGINT ,
                        @BLOCK_BRANCH_ID BIGINT ,
                        @ROOM_SIZE_OUTER NUMERIC(10, 2)
                    SET @ERR_CODE = '1.4.1'
                    DECLARE CR_LAYER CURSOR
                    FOR
                        SELECT  ROOM_NO ,
                                ROOM_SHAPE ,
                                ROOM_SIZE ,
                                ROOM_SIZE_INNER ,
                                ROOM_SIZE_OUTER
                        FROM    dbo.T_INPOUR_DATA
                        WHERE   GUID_VALUE = @GUID_VALUE
                                AND PROJ_NAME = @PROJ_NAME
                                AND G_NAME = @G_NAME
                                AND BLOCK_NAME = @BLOCKNAME
                       
   
                    OPEN CR_LAYER
                    FETCH NEXT FROM CR_LAYER INTO @ROOM_NO, @ROOM_SHAPE,
                        @ROOM_SIZE, @ROOM_SIZE_INNER, @ROOM_SIZE_OUTER
                    WHILE ( @@FETCH_STATUS = 0 ) 
                        BEGIN
                            IF LEN(@ROOM_NO) < 4 
                                BEGIN
                                    SET @LAYER_NUM = CAST(SUBSTRING(@ROOM_NO,
                                                              1, 1) AS INT)
                                    SET @BRACH_NUM = CAST(SUBSTRING(@ROOM_NO,
                                                              2, 2) AS INT) 
                                END
                            ELSE 
                                BEGIN
                                    SET @LAYER_NUM = CAST(SUBSTRING(@ROOM_NO,
                                                              1, 2) AS INT)
                                    SET @BRACH_NUM = CAST(SUBSTRING(@ROOM_NO,
                                                              3, 2) AS INT)
                                END 
                            SELECT  @BLOCK_BRANCH_ID = BLOCK_BRANCH_ID
                            FROM    dbo.T_BLOCK_BRANCH
                            WHERE   BLOCK_ID = @BLOCKID
                                    AND BRANCH_NUM = @BRACH_NUM
                            SELECT  @BLOCK_LAYER_ID = BLOCK_LAYER_ID
                            FROM    dbo.T_BLOCK_LAYER
                            WHERE   BLOCK_ID = @BLOCKID
                                    AND LAYER_NUM = @LAYER_NUM
                            INSERT  INTO T_ROOM
                                    ( BLOCK_ID ,
                                      BLOCK_LAYER_ID ,
                                      BLOCK_BRANCH_ID ,
                                      ROOM_NO ,
                                      ROOM_SHAPE ,
                                      ROOM_SIZE ,
                                      ROOM_SIZE_INNER ,
                                      ROOM_SIZE_OUTER
                                    )
                            VALUES  ( @BLOCKID ,
                                      @BLOCK_LAYER_ID ,
                                      @BLOCK_BRANCH_ID ,
                                      @ROOM_NO ,
                                      @ROOM_SHAPE ,
                                      @ROOM_SIZE ,
                                      @ROOM_SIZE_INNER ,
                                      @ROOM_SIZE_OUTER
                                    ) 
                            FETCH NEXT FROM CR_LAYER INTO @ROOM_NO,
                                @ROOM_SHAPE, @ROOM_SIZE, @ROOM_SIZE_INNER,
                                @ROOM_SIZE_OUTER
                        END
                    CLOSE CR_LAYER
                    DEALLOCATE CR_LAYER
                    FETCH NEXT FROM CR_TOTAL INTO @BLOCKNAME, @G_NAME,
                        @PROJ_NAME
                END
            CLOSE CR_TOTAL
            DEALLOCATE CR_TOTAL 
            --刪除導入dbo.T_INPOUR_DATA的數據
            DELETE  FROM dbo.T_INPOUR_DATA
            WHERE   GUID_VALUE = @GUID_VALUE
            SET @RESULT = 1
                    
            SET @RESULTMSG = '導入數據成功!'
            COMMIT TRANSACTION
        END TRY
        BEGIN CATCH
            SET @RESULT = 0
            SET @RESULTMSG = '出現錯誤!錯誤信息:' + @ERROMESSAGE
            ROLLBACK TRANSACTION
            
        END CATCH 
    END

拋出異常的方式:

USE [JGB_DB]
GO
/****** 對象:  StoredProcedure [dbo].[P_GENERATE_BLOCK_DIMENSION]    腳本日期: 08/13/2013 09:02:58 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE PROCEDURE [dbo].[P_GENERATE_BLOCK_DIMENSION]
/*增、刪、改 建樓、樓層、樓單元和房間*/
    @GR_ID                BIGINT,       --地塊id
    @BLOCK_ID             BIGINT,      --樓ID  "如果新建,傳NULL"
    @BLOCK_NAME           varchar(30),  --樓名稱
    /*@PICTURE_PATH         varchar(200), --樓總平面圖文件所在路徑*/
    @BLOCK_ORDER          INT,          --樓序號
    
    @LAYER_CNT            INT,          --樓層數
    @BRANCH_CNT           INT,          --單元數
    
    @OPER_TYPE            VARCHAR(2),   --操作類型 "增,刪,替"
    
    @NEW_BLOCK_ID        BIGINT        OUTPUT,    --返回的block_id,如果刪除和異常返回 null ,替不變,改,增,為新id
    @RESULTMSG          VARCHAR(1000) OUTPUT,    --錯誤消息
    @RESULT               BIT           OUTPUT     --返回消息  1正確,0錯誤

AS
BEGIN
        DECLARE 
                @I  INT, @J INT,
                @BLOCK_LAYER_ID BIGINT,@LAYER_NUM INT,
                @BLOCK_BRANCH_ID BIGINT,@BRANCH_NUM INT,
                @LAYER_NO VARCHAR(2),@BRANCH_NO VARCHAR(2)
                
        
        DECLARE @POS_FN INT, @POS_FV INT, @POS_PR INT --臨時變量用於存儲,的位置
        DECLARE @CHOOSEROOM_FAMILY_CNT INT
        DECLARE @ERR_CODE VARCHAR(200)
        
        BEGIN TRY
            BEGIN TRANSACTION
               --查詢是否選擇
               IF (@BLOCK_ID is not null)--(@OPER_TYPE IN ('改','刪','替'))  --改 或 刪,替
               BEGIN                    
                       SELECT @CHOOSEROOM_FAMILY_CNT = COUNT(ROOM_ID) FROM T_ROOM WHERE BLOCK_ID = @BLOCK_ID AND SETTLE_ID IS NOT NULL
                       IF @CHOOSEROOM_FAMILY_CNT = 0 
                       BEGIN
                           IF @OPER_TYPE = ''
                           BEGIN
                               GOTO Branch_Generate
                           END
                        ELSE 
                        BEGIN                        
                            
                               --刪除房間、樓層、單元、樓
                               DELETE FROM T_ROOM           WHERE BLOCK_ID = @BLOCK_ID
                               DELETE FROM T_BLOCK_LAYER  WHERE BLOCK_ID = @BLOCK_ID
                               DELETE FROM T_BLOCK_BRANCH WHERE BLOCK_ID = @BLOCK_ID
                               DELETE FROM T_BLOCK           WHERE BLOCK_ID = @BLOCK_ID
                               
                               IF @OPER_TYPE = '' 
                                GOTO Branch_DELOK
                               ELSE --
                                   GOTO Branch_Generate

                        END
                           

                       END
                       ELSE  --房源已被選
                          GOTO Branch_Donothing    
               END
               ELSE --
               BEGIN
                       GOTO Branch_Generate
               END
             
              Branch_Generate: -- 增,替 和 改
               
               IF @OPER_TYPE = '' 
               BEGIN
 
                         UPDATE T_BLOCK
                         SET GR_ID = @GR_ID
                             ,BLOCK_NAME = @BLOCK_NAME
                             /*,PICTURE_PATH = @PICTURE_PATH*/
                             ,BLOCK_ORDER = @BLOCK_ORDER
                         WHERE BLOCK_ID=@BLOCK_ID
                         
                      

                         SET @RESULT = 1
                      SET @NEW_BLOCK_ID = @BLOCK_ID
                      SET @RESULTMSG = @OPER_TYPE + '成功!'
                      COMMIT TRANSACTION
                    
                      Goto Branch_End
               END
               ELSE --增 和 改
               BEGIN
                          --生成樓
                          SET @ERR_CODE = '1.0'
                       INSERT INTO T_BLOCK(GR_ID,BLOCK_NAME,BLOCK_ORDER)
                       VALUES(@GR_ID,@BLOCK_NAME,@BLOCK_ORDER)
                       
                       SET @BLOCK_ID = IDENT_CURRENT('T_BLOCK') --SCOPE_IDENTITY()  
                       --生成樓層
                       SET @ERR_CODE = '1.2'
                       
                       SET @I=1
                       WHILE @I <= @LAYER_CNT
                       BEGIN
                              INSERT INTO T_BLOCK_LAYER(BLOCK_ID,LAYER_NUM)
                              VALUES(@BLOCK_ID,@I)
                              
                              SET @I = @I + 1
                       END
                       --生成單元
                       SET @ERR_CODE = '1.3'
                       SET @I=1
                       WHILE @I <= @BRANCH_CNT
                       BEGIN
                              INSERT INTO T_BLOCK_BRANCH(BLOCK_ID,BRANCH_NUM)
                              VALUES(@BLOCK_ID,@I)
                              
                              SET @I = @I + 1
                       END
                       
                        --生成房屋
                        
                        SET @ERR_CODE = '1.4.1'

                      DECLARE CR_LAYER CURSOR FOR 
                        SELECT BLOCK_LAYER_ID,LAYER_NUM FROM T_BLOCK_LAYER 
                        WHERE BLOCK_ID=@BLOCK_ID
                        ORDER BY LAYER_NUM    
                       
   
                        OPEN CR_LAYER
                      
                       
                       FETCH NEXT FROM CR_LAYER INTO @BLOCK_LAYER_ID,@LAYER_NUM

                       WHILE (@@FETCH_STATUS = 0)
                       BEGIN
                                 SET @ERR_CODE = '1.4.3.0'
                                --IF @LAYER_NUM < 10
                                   --SET @LAYER_NO = '0' + CONVERT(VARCHAR(1),@LAYER_NUM)
                                --ELSE 
                                    SET @LAYER_NO = CONVERT(VARCHAR(2),@LAYER_NUM)
                                
                                --游標要臨時創建    
                                 DECLARE CR_BRANCH CURSOR FOR 
                             SELECT BLOCK_BRANCH_ID,BRANCH_NUM FROM T_BLOCK_BRANCH 
                             WHERE BLOCK_ID=@BLOCK_ID
                             ORDER BY BRANCH_NUM
                                
                                OPEN CR_BRANCH
                             FETCH NEXT FROM CR_BRANCH INTO @BLOCK_BRANCH_ID,@BRANCH_NUM
                             WHILE (@@FETCH_STATUS = 0)
                             BEGIN
                                 IF @BRANCH_NUM<10
                                       SET @BRANCH_NO = '0' + CONVERT(VARCHAR(1),@BRANCH_NUM)
                                    ELSE 
                                        SET @BRANCH_NO = CONVERT(VARCHAR(2),@BRANCH_NUM)
                                
                                INSERT INTO T_ROOM(BLOCK_ID,BLOCK_LAYER_ID,BLOCK_BRANCH_ID,ROOM_NO)
                                VALUES(@BLOCK_ID,@BLOCK_LAYER_ID,@BLOCK_BRANCH_ID,@LAYER_NO + @BRANCH_NO)
                          
                                 
                                   FETCH NEXT FROM CR_BRANCH INTO @BLOCK_BRANCH_ID,@BRANCH_NUM
                             END
                            CLOSE CR_BRANCH
                            DEALLOCATE CR_BRANCH    
                                                       
                               FETCH NEXT FROM CR_LAYER INTO @BLOCK_LAYER_ID,@LAYER_NUM
                       END
                       
                       CLOSE CR_LAYER
                       DEALLOCATE CR_LAYER
                       
                    SET @NEW_BLOCK_ID = @BLOCK_ID
                    SET @RESULT = 1
                    
                    SET @RESULTMSG = @OPER_TYPE + '成功!' +  isnull(@ERR_CODE ,'')
                    COMMIT TRANSACTION
                    
                    Goto Branch_End

               END
            
            Branch_Donothing:
                SET @NEW_BLOCK_ID = NULL
                SET @RESULT = 0
                SET @RESULTMSG = '該房源已被選,無法修改!'
                COMMIT TRANSACTION
                 Goto Branch_End
            
            Branch_DELOK:
                SET @NEW_BLOCK_ID = NULL
                SET @RESULT = 1
                SET @RESULTMSG = '刪除成功!'
                COMMIT TRANSACTION
                Goto Branch_End
            
                
            Branch_End:
        END TRY
        BEGIN CATCH
            SET @NEW_BLOCK_ID = NULL
            SET @RESULT = 0
            SET @RESULTMSG = '出現錯誤!錯誤代碼:' + @ERR_CODE
            ROLLBACK TRANSACTION
            
        END CATCH
        


END

上面的代碼注意的是:在你goto   Branch_End之前,一定要先提交事務才去跳轉


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com