美文网首页
sql server存储过程案例模板

sql server存储过程案例模板

作者: 吉凶以情迁 | 来源:发表于2023-03-31 16:27 被阅读0次
    CREATE PROCEDURE OrderProcessing
        @OrderID INT
    AS
    BEGIN
        -- 判断订单是否存在
        IF NOT EXISTS (SELECT * FROM Orders WHERE OrderID = @OrderID)
        BEGIN
            RAISERROR ('Invalid order ID', 16, 1)
            RETURN
        END
    
        -- 获取订单状态
        DECLARE @Status VARCHAR(20)
        SELECT @Status = Status FROM Orders WHERE OrderID = @OrderID
    
        -- 根据订单状态执行不同的操作
        IF @Status = 'New'
        BEGIN
            UPDATE Orders SET Status = 'Processing' WHERE OrderID = @OrderID
            EXEC StartOrderProcessing @OrderID
        END
        ELSE IF @Status = 'Processing'
        BEGIN
            DECLARE @Attempts INT
            SET @Attempts = 0
    
            WHILE @Attempts < 3
            BEGIN
                -- 模拟订单处理过程中断
                WAITFOR DELAY '00:00:10'
    
                -- 检查订单处理是否完成
                IF EXISTS (SELECT * FROM OrderProcessingLog WHERE OrderID = @OrderID AND CompleteTime IS NOT NULL)
                BEGIN
                    UPDATE Orders SET Status = 'Completed' WHERE OrderID = @OrderID
                    EXEC NotifyCustomer @OrderID
                    BREAK
                END
                ELSE
                BEGIN
                    SET @Attempts = @Attempts + 1
                END
            END
    
            IF @Attempts = 3
            BEGIN
                -- 处理失败,通知客服人员
                EXEC NotifySupport @OrderID
            END
        END
        ELSE IF @Status = 'Completed'
        BEGIN
            RAISERROR ('This order has already been completed', 16, 1)
            RETURN
        END
    END
    
    

    该存储过程的逻辑如下:

    首先判断指定的订单是否存在。如果不存在,抛出一个异常并退出存储过程。
    获取订单的状态,并根据不同的状态执行不同的操作。
    如果订单状态是 New,则将其状态更新为 Processing 并调用名为 StartOrderProcessing 的存储过程,开始处理订单。
    如果订单状态是 Processing,则重复执行以下步骤,直到订单处理完成或尝试次数达到 3 次:
    等待 10 秒钟(模拟订单处理过程中断)。
    检查订单处理是否已经完成。
    如果处理完成,则将订单状态更新为 Completed、调用名为 NotifyCustomer 的存储过程通知客户,并退出循环。
    如果未完成,则增加尝试次数。
    如果尝试次数达到 3 次,则认为处理失败,调用名为 NotifySupport 的存储过程通知客服人员。
    如果订单状态是 Completed,则抛出一个异常并退出存储过程。
    该存储过程涉及到许多高级语法和逻辑,包括条件判断、循环、异常处理等。通过这个示例,您可以更好地理解 SQL Server 存储过程的复杂性,并了解如何使用它们来管理复杂的业务逻辑。

    CalculateEmployeeSalary,它接受三个输入参数 @EmployeeID、@StartDate 和 @EndDate,并计算指定员工在指定时间段内的薪水总额,并将结果作为输出参数返回。该存储过程的逻辑如下:

    CREATE PROCEDURE CalculateEmployeeSalary
        @EmployeeID INT,
        @StartDate DATE,
        @EndDate DATE,
        @TotalSalary MONEY OUTPUT
    AS
    BEGIN
        DECLARE @Salary MONEY
    
        -- 计算薪水总额
        SELECT @Salary = SUM(Salary)
        FROM SalaryHistory
        WHERE EmployeeID = @EmployeeID
        AND StartDate >= @StartDate
        AND EndDate <= @EndDate
    
        -- 设置输出参数
        SET @TotalSalary = @Salary
    END
    

    举例

    CREATE PROCEDURE [dbo].[proc_AddOrUpdate_CustomParts]
        @id BIGINT,
        @PartNumber VARCHAR(50),
        @BPartNumber VARCHAR(50),
        @GroupName VARCHAR(50),
        @VendorFill VARCHAR(50),
        @InternalVersion VARCHAR(50),
        @CustomerInternalEngineering VARCHAR(50),
        @UserName VARCHAR(50),
        @ReturnCode INT OUTPUT,
        @ReturnMSG VARCHAR(200) OUTPUT
    AS
    BEGIN
        DECLARE @NewID INT, @count INT;
        
        -- 初始化返回值
        SELECT @ReturnCode = -1, @ReturnMSG = '失败';
    
        -- 开始事务处理
        BEGIN TRAN gusn;
    
        IF (@id > 0)
        BEGIN
            -- 更新现有客制化零件信息
            UPDATE Custom_Parts SET VendorFill = @VendorFill, InternalVersion = @InternalVersion, CustomerInternalEngineering = @CustomerInternalEngineering, WhoUpdate = @UserName, UpdateDate = GETDATE()
            WHERE id = @id;
            
            -- 检查是否更新成功
            IF @@ERROR <> 0
            BEGIN
                -- 如果发生错误,回滚事务并退出
                GOTO ErrTransHandle;
            END
    
            -- 将旧记录插入到历史表中进行备份
            INSERT INTO Custom_Parts_History SELECT * FROM Custom_Parts WHERE id = @id;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
    
            -- 更新 Custom_Parts_Detail 表中对应的记录
            UPDATE Custom_Parts_Detail SET id = @id WHERE PartNumber = @PartNumber AND BPartNumber = @BPartNumber AND GroupName = @GroupName;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
    
            -- 将旧记录插入到历史表中进行备份
            INSERT INTO Custom_Parts_Detail_History SELECT * FROM Custom_Parts_Detail WHERE id = @id;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
        END
        ELSE
        BEGIN
            -- 检查是否已经存在相同的零件分组
            SELECT @count = COUNT(*) FROM Custom_Parts WHERE PartNumber = @PartNumber AND BPartNumber = @BPartNumber AND GroupName = @GroupName;
    
            IF (@count > 0)
            BEGIN
                -- 如果零件分组已存在,设置返回消息并退出
                SELECT @ReturnMSG = '已维护';
                GOTO ErrTransHandle;
            END
    
            -- 添加新的客制化零件信息
            INSERT INTO Custom_Parts (PartNumber, BPartNumber, GroupName, VendorFill, InternalVersion, CustomerInternalEngineering, WhoRec) VALUES 
                                     (@PartNumber, @BPartNumber, @GroupName, @VendorFill, @InternalVersion, @CustomerInternalEngineering, @UserName);
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
    
            SET @NewID = @@IDENTITY;
    
            -- 将新记录插入到历史表中进行备份
            INSERT INTO Custom_Parts_History SELECT * FROM Custom_Parts WHERE id = @NewID;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
    
            -- 更新 Custom_Parts_Detail 表中对应的记录
            UPDATE Custom_Parts_Detail SET id = @NewID WHERE PartNumber = @PartNumber AND BPartNumber = @BPartNumber AND GroupName = @GroupName;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
    
            -- 将新记录插入到历史表中进行备份
            INSERT INTO Custom_Parts_Detail_History SELECT * FROM Custom_Parts_Detail WHERE id = @NewID;
            IF @@ERROR <> 0
            BEGIN
                GOTO ErrTransHandle;
            END
        END
        
        -- 设置返回值并提交事务
        SELECT @ReturnCode = 0, @ReturnMSG = '成功';
        COMMIT TRAN gusn;
        RETURN @ReturnCode;
    
    ErrHandle:
        RETURN @ReturnCode;
    
    ErrTransHandle:
        -- 回滚事务并设置返回值
        ROLLBACK TRAN gusn;
        RETURN @ReturnCode;
    END;
    

    IF OBJECT_ID('dbo.MyStoredProcedure', 'P') IS NOT NULL
        DROP PROCEDURE dbo.MyStoredProcedure
    GO
    
    CREATE PROCEDURE dbo.MyStoredProcedure
        @inputString VARCHAR(MAX)
    AS
    BEGIN
        SET NOCOUNT ON;
        
        BEGIN TRY
            BEGIN TRANSACTION
            
            DECLARE @tempTable TABLE (id INT, name VARCHAR(50), age INT)
            
            -- 将输入字符串拆分为临时表
            INSERT INTO @tempTable
            SELECT 
                CAST(LEFT(item, CHARINDEX(',', item) - 1) AS INT), 
                SUBSTRING(item, CHARINDEX(',', item) + 1, LEN(item)), 
                NULL
            FROM 
                STRING_SPLIT(@inputString, ';')
                
            -- 检查最后一条 SQL 语句是否有错误
            IF @@ERROR != 0
                GOTO ErrorHandler; 
            
            -- 根据姓名匹配更新年龄列
            UPDATE 
                t
            SET 
                t.age = c.age
            FROM 
                @tempTable t
            INNER JOIN 
                dbo.Customers c ON t.name = c.name
            
            -- 检查最后一条 SQL 语句是否有错误
            IF @@ERROR != 0
                GOTO ErrorHandler; 
            
            -- 如果没有更新行,则引发错误
            IF @@ROWCOUNT = 0
            BEGIN
                RAISERROR('没有更新行。', 16, 1)
                GOTO ErrorHandler;
            END
            
            -- 将年龄转换为字符串,并使用 CASE WHEN 语句设置消息
            DECLARE @ageMessage VARCHAR(100)
            SET @ageMessage = 
                CASE 
                    WHEN MAX(t.age) < 18 THEN '年轻人'
                    WHEN MAX(t.age) >= 18 AND MAX(t.age) <= 65 THEN '成年人'
                    ELSE '老年人'
                END
            
            -- 打印带有年龄类别的消息
            PRINT '列表中最年长的人是:' + @ageMessage
            
            COMMIT TRANSACTION
        END TRY
        BEGIN CATCH
            IF @@TRANCOUNT > 0
                ROLLBACK TRANSACTION
            
            -- 打印错误消息及其详细信息
            PRINT '错误:' + ERROR_MESSAGE() + ',行:' + CAST(ERROR_LINE() AS VARCHAR(10))
            
            -- 返回错误代码
            RETURN @@ERROR;
        END CATCH
        
        -- 如果没有出现错误,则返回 0
        RETURN 0;
    
    ErrorHandler:
        IF @@TRANCOUNT > 0
            ROLLBACK TRANSACTION;
        
        -- 返回错误代码
        RETURN @@ERROR;
    END
    GO
    
    

    EXEC dbo.MyStoredProcedure '1,John;2,Jane;3,Bob;'

    在这个例子中,假设 Customers 表中有如下数据:

    id name age
    1 John 24
    2 Jane 33
    3 Alice 12
    4 Bob 47
    因此,存储过程将打印出以下消息:

    The oldest person in the list is a(n) Adult

    高级语法之发起http业务
    IF CHARINDEX('{', @responseText) = 0判断是否存在{
    @access_token = JSON_VALUE(@JSON, '$.access_token');
    从json字符串解析键access_token
    ,内容为{ "accesstoken":"xxxxxxxxxx"}

    ALTER   PROCEDURE [dbo].[SendMessageToWechat] 
        @corp_id varchar(50),
        @secret varchar(50),
        @touser varchar(50),
        @agent_id varchar(50),
        @content varchar(500),
        @returnResult varchar(8000) output,
        @returnCode int output,
        @returnMsg varchar(8000) output
    AS
    BEGIN
    
        DECLARE @Object INT;
        DECLARE @Url VARCHAR(2000);
        DECLARE @Result VARCHAR(MAX);
        DECLARE @access_token VARCHAR(800);
        declare @errmsg varchar(500);
        DECLARE @POST VARCHAR(MAX);
        SET @Url = 'https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=' + @corp_id + '&corpsecret=' + @secret;
    
    DECLARE @return_value int,
            @responseText varchar(8000),
            @responseStatus varchar(800),
            @responseCode varchar(800)
    set @responseCode='900'
    EXEC    @return_value = [dbo].[SP_HTTPRequest]
            @URI = @Url,
            @methodName = N'get',
            @responseText = @responseText OUTPUT,
            @responseStatus = @responseStatus OUTPUT,
            @responseCode = @responseCode OUTPUT
        IF @responseCode<>'200'
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=CAST(@responseCode AS INT);
            set @returnMsg='GetTokenFail,HttpResponseError  StatusCode is'+@responseCode;
            RETURN;
        END
        IF  CHARINDEX('{', @responseText) = 0
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=800;
            set @returnMsg='GetTokenFail,ParseJSONFormatError ,Content Format Error';
            RETURN;
        END
    
        DECLARE @JSON NVARCHAR(MAX) = @responseText;
        DECLARE @errcode INT = JSON_VALUE(@JSON, '$.errcode');
    
        IF @errcode <> 0
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=800;
            set @returnMsg='GetTokenFail,pusherrcode is '+@errcode;
          
            RETURN;
        END
    
        set @access_token = JSON_VALUE(@JSON, '$.access_token');
    
        SET @POST = '{
            "touser": "' + @touser + '",
            "agentid": ' + @agent_id + ',
            "is_to_all": true,
            "msgtype": "text",
            "text": {
                "content": "' + @content + '"
            }
        }';
    
        SET @Url = 'https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token='+ @access_token;
        EXEC    @return_value = [dbo].[SP_HTTPRequest]
            @URI = @Url,
            @methodName = N'post',
            @requestBody = @POST, 
            @responseText = @responseText OUTPUT,
            @responseStatus = @responseStatus OUTPUT,
            @responseCode = @responseCode OUTPUT
        IF @responseCode<>'200'
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=CAST(@responseCode AS int);
            set @returnMsg='SendFail,HttpResponseError  StatusCode is'+@responseCode;
            RETURN;
        END
        IF  CHARINDEX('{', @responseText) = 0
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=800;
            set @returnMsg='SendFail,ParseJSONFormatError ,Content Format Error';
            RETURN;
        END
         set @JSON = @responseText;
         --select JSON_VALUE(@JSON, '$.errcode')
        set  @errcode  =CAST(JSON_VALUE(@JSON, '$.errcode') as int);
    
        set  @errmsg  =JSON_VALUE(@JSON, '$.errmsg');
        IF @errcode <> 0
        BEGIN
            set @returnResult=@responseText;
            set @returnCode=800;
            set @returnMsg='PushFail,Pusherrcode is '+cast(@errcode as varchar(100))+ ' '+@errmsg --+' token is '+@access_token;
            RETURN;
        END
        set @returnResult=@responseText;
        set @returnCode=200;
        set @returnMsg='PushSuccess';
    END
    

    相关文章

      网友评论

          本文标题:sql server存储过程案例模板

          本文链接:https://www.haomeiwen.com/subject/pvbfddtx.html