美文网首页
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