SQL Server 存储过程开发手册

SQL Server 存储过程开发手册(更新版)

根据要求,重新整理并加入了事务控制、异常日志记录和返回状态码的设计。以下是详细说明:


1. 总则

1.1 目标

本手册旨在为 SQL Server 存储过程的编写提供一套完整的规范,确保系统的事务控制、异常处理、日志记录和状态码返回清晰明确,优化数据一致性、系统稳定性和性能。


2. 事务控制与层次化设计

2.1 事务控制原则

根据业务的需求和事务的粒度,存储过程应分为不同的层次,每个层次的事务控制和异常处理策略不同,具体如下表所示:

层次控制事务记录异常日志返回状态码
主流程 (Main)
子事务 (SubTx)
功能性操作 (Func)可选
  • 主流程 (Main)

    • 不控制事务,负责协调和调用子事务或功能性操作。

    • 记录异常日志,捕获并输出错误信息。

    • 返回状态码,以通知调用方执行状态(成功或失败)。

  • 子事务 (SubTx)

    • 控制事务,开始和提交或回滚事务。

    • 记录异常日志,在发生异常时捕获并输出错误信息。

    • 返回状态码,标识事务是否成功完成。

  • 功能性操作 (Func)

    • 不控制事务,通常是读取操作或不涉及数据修改的辅助功能。

    • 不记录异常日志(除非必要),通常这些操作在主流程中捕获异常。

    • 返回状态码可选,根据具体业务需要决定是否返回。


3. 存储过程命名规范

存储过程命名应该遵循以下结构,便于识别和维护:

proc_领域_子领域_类型
  • 领域 (Domain):表示存储过程所属的业务领域,如订单、用户、商品等。

  • 子领域 (SubDomain):表示存储过程在领域中的具体细分模块,如发货、支付、库存等。

  • 类型 (Type):表示存储过程的类型,分为三种类型:

    • Main:主流程,负责协调其他子事务和功能性操作。

    • SubTx:子事务,负责数据更新和事务控制。

    • Func:功能性操作,通常是查询或计算操作。

3.1 示例命名

  • proc_Order_Shipment_SubTx:表示“订单”领域中的“发货”子领域的子事务,涉及事务控制。

  • proc_Order_Payment_Main:表示“订单”领域中的“支付”子领域的主流程,负责调用其他子事务。

  • proc_Inventory_Check_Func:表示“库存”领域中的“检查”功能,通常用于查询操作,不涉及事务控制。


4. 存储过程设计与事务控制

4.1 主流程存储过程

主流程存储过程不涉及事务控制,它的职责是调用子事务和功能性操作,并记录异常日志和返回执行状态码。

CREATE PROCEDURE proc_Order_Shipment_Main@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGINBEGIN TRY-- 调用子事务,子事务控制事务EXEC proc_Order_Shipment_SubTx @OrderId, @code,@msg  ;if(@code!=200){-- 记录失败原因,处理失败带来的影响return}-- 调用功能性操作(如果需要)EXEC proc_Inventory_Check_Func @OrderId, @code,@msg ;if(@code!=200){-- 记录失败原因,处理失败带来的影响return}-- 返回成功状态码set @code=200END TRYBEGIN CATCH-- 捕获并记录异常日志PRINT 'Error in proc_Order_Shipment_Main: ' + ERROR_MESSAGE();-- 返回失败状态码RETURN 1; -- 状态码:1 表示失败END CATCH
END;

4.2 子事务存储过程

子事务存储过程负责控制事务,它需要开始、提交和回滚事务,并在发生异常时记录日志和返回状态码。

CREATE PROCEDURE proc_Order_Shipment_SubTx@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGIN-- 开始事务BEGIN TRANSACTION;BEGIN TRY-- 订单发货相关的数据库操作UPDATE dbo.OrderSET ShipmentStatus = 'Shipped'WHERE OrderId = @OrderId;-- 提交事务COMMIT TRANSACTION;-- 返回成功状态码RETURN 0; -- 状态码:0 表示成功END TRYBEGIN CATCH-- 发生错误时回滚事务ROLLBACK TRANSACTION;-- 记录异常日志PRINT 'Error in proc_Order_Shipment_SubTx: ' + ERROR_MESSAGE();-- 返回失败状态码RETURN 1; -- 状态码:1 表示失败END CATCH
END;

4.3 功能性操作存储过程

功能性操作通常是只执行查询或计算,不涉及数据修改,因此不控制事务。日志记录和状态码返回可选,具体业务需求决定。

CREATE PROCEDURE proc_Inventory_Check_Func@OrderId INT,@code INT output,@msg varchar(500) output
AS
BEGIN-- 查询操作,检查库存SELECT ProductId, AvailableStockFROM dbo.InventoryWHERE ProductId IN (SELECT ProductId FROM dbo.OrderItems WHERE OrderId = @OrderId);
END;

5. 错误处理与日志记录

5.1 错误处理

  • 主流程:主流程存储过程捕获所有子事务和功能性操作中的异常,但不控制事务回滚。它应当记录异常日志,并返回相应的状态码(通常是 0 或 1)。

  • 子事务:子事务存储过程必须通过 BEGIN TRYBEGIN CATCH 语句来捕获异常,并在异常发生时回滚事务。所有异常都应该记录日志,并返回状态码,标识事务是否成功。

  • 功能性操作:功能性操作通常不捕获异常,也不记录日志,异常处理依赖于主流程。

5.2 异常日志记录

所有的异常都应通过日志记录下来,方便后期排查和优化。可以使用 PRINTRAISEERROR 语句来记录错误消息。

BEGIN CATCHPRINT 'Error: ' + ERROR_MESSAGE();-- 或者使用 RAISEERROR 记录更详细的日志-- RAISEERROR('Error in procedure: %s', 16, 1, ERROR_MESSAGE());THROW;
END CATCH

6. 返回状态码

每个存储过程在执行完毕后应返回一个状态码,状态码通常为:

  • 0:表示操作成功。

  • 1:表示操作失败(可根据需要扩展更多状态码,表示不同类型的错误)。

返回状态码用于调用方判断存储过程执行是否成功,并做相应的处理。


7. 性能优化与锁争用

  • 避免长事务:事务内只包含必要的数据库操作,避免外部接口或延时任务的调用。

  • 批量处理:对于需要更新大量数据的操作,尽量使用批量处理,减少事务锁的持有时间。

  • 索引优化:确保数据库表有适当的索引,以加速查询和数据操作。


8. 审查与监控

8.1 代码审查标准

  • 确保每个存储过程的事务控制符合规范。

  • 确保异常处理机制完备,并且日志记录充分。

  • 确保存储过程有清晰的返回状态码,便于系统监控。

8.2 监控与日志

  • 监控长时间运行的事务,避免事务阻塞。

  • 配置合适的告警机制,及时捕获死锁或其他异常。


总结

  • 通过分层设计,每个存储过程的责任清晰,主流程不控制事务,子事务控制事务,功能性操作不涉及事务管理。

  • 存储过程命名规则统一,便于后续维护和扩展。

  • 错误处理和日志记录是保证系统稳定性的关键,每个存储过程都应有明确的异常处理和日志记录机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/81259.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深海科技服务博客简介

人人可学,人人可用,IT与AI不是高不可攀! 博客宗旨 深海科技服务博客致力于: 推广IT与AI的实际应用,降低入门门槛,让更多个人和中小企业能够以最少投入、高效实现信息化、智能化。 分享开源免费软件、简单…

本地大模型编程实战(29)查询图数据库NEO4J(2)

上一篇文章 用大语言模型LLM查询图数据库NEO4J(1) 介绍了使用GraphQACypherChain查询NEO4J。用它实现简单快捷,但是不容易定制,在生产环境中可能会面临挑战。 本文将基于langgraph 框架,用LLM(大语言模型)查询图数据库NEO4J。它可以定义清晰复…

RPG_5.角色动画

1.创建一个动画实例 2.创建该实例的c子类 3.继续创建该类的子类,但是作用是用来链接(以后会详细解释) 4.基于PlayerAnimInstance类创建一个子类 5.目前一共创建了四个c类, 最基的类 角色的类 玩家控制的角色的类 玩家控制的角…

Sigmoid函数导数推导详解

Sigmoid函数导数推导详解 在逻辑回归中,Sigmoid函数的导数推导是一个关键步骤,它使得梯度下降算法能够高效地计算。 1. Sigmoid函数定义 首先回顾Sigmoid函数的定义: g ( z ) 1 1 e − z g(z) \frac{1}{1 e^{-z}} g(z)1e−z1​ 2. 导…

MS31860T——8 通道串行接口低边驱动器

MS31860T 是一款 8 通道低边驱动器,包含 SPI 串口通信、 PWM斩波器配置、过流保护、短路保护、欠压锁定和过热关断功能, 芯片可以读取每个通道的状态。MS31860T 可以诊断开路的负载情况,并可以读取故障信息。外部故障引脚指示芯片的故障状态。…

腾讯 Kuikly 正式开源,了解一下这个基于 Kotlin 的全平台框架

在 3月的时候通过 《腾讯 TDF 即将开源 Kuikly 跨端框架,Kotlin 支持全平台》 我们大致知道了 Kuikly 的基本情况,Kuikly 是一个面向终端技术栈的跨端开发框架,完全基于kotlin语言开发,提供原生的性能和体验。 按照官方的说法&…

AI驱动UI自动化测试框架调研

随着应用复杂度增加,手动测试变得费时且易出错,而自动化测试可提高效率和可靠性。如何借助大模型和一些自动化测试框架进行自动化测试,是一个研发团队很重要的诉求。 目前主流的自动化测试框架很多,Midscene.js结合Playwright提供…

关系型数据库设计指南

1. 前言 在自己独立开发一个项目的过程中,我发现了一些以往写小 Demo 从来没有遇到过的问题。 最近在独立制作一个全栈的通知管理平台。一开始我没有考虑太多,直接根据头脑中零星的想法就开撸后端数据库 model 和 API,用的是学了半成品的 M…

详解TypeScript中的类型断言及其绕过类型检查机制

TypeScript中的类型断言及其绕过类型检查机制 一、类型断言的本质与工作原理编译时与运行时的区别TypeScript编译器处理类型断言的步骤 二、类型断言的详细语法与进阶用法基础语法对比链式断言断言修饰符1. 非空断言操作符 (!)代码分析1. getLength 函数分析用法说明&#xff1…

XLSX.utils.sheet_to_json设置了blankrows:true,但无法获取到开头的空白行

在用sheetJs的XLSX库做导入,遇到一个bug。如果开头行是空白行的话,调用sheet_to_json转数组获得的数据也是没有包含空白行的。这样会导致在设置对应的起始行时,解析数据不生效。 目前是直接跳过了开头的两行空白行 正确应该获得一下数据 问…

PostgreSQL 数据库下载和安装

官网: PostgreSQL: Downloads 推荐下载网站:EDB downloads postgresql 我选了 postgresql-15.12-1-windows-x64.exe 鼠标双击,开始安装: 安装路径: Installation Directory: D:\Program Files\PostgreSQL\15 Serv…

一、Javaweb是什么?

1.1 客户端与服务端 客户端 :用于与用户进行交互,接受用户的输入或操作,且展示服务器端的数据以及向服务器传递数据。 例如:手机app,微信小程序、浏览器… 服务端 :与客户端进行交互,接受客户…

奇偶ASCII值判断

奇偶ASCII值判断 Description 任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO。例如,字符A的ASCII值是65,则输出YES,若输入字符B(ASCII值是66),则输…

OpenCV 图形API(74)图像与通道拼接函数-----合并三个单通道图像(GMat)为一个多通道图像的函数merge3()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 从3个单通道矩阵创建一个3通道矩阵。 此函数将多个矩阵合并以生成一个单一的多通道矩阵。即,输出矩阵的每个元素将是输入矩阵元素的…

多节点监测任务分配方法比较与分析

多监测节点任务分配方法是分布式系统、物联网(IoT)、工业监测等领域的核心技术,其核心目标是在资源受限条件下高效分配任务,以优化系统性能。以下从方法分类、对比分析、应用场景选择及挑战等方面进行系统阐述: 图1 多…

【推荐系统笔记】BPR损失函数公式

一、BPR损失函数公式 BPR 损失函数的核心公式如下: L BPR − ∑ ( u , i , j ) ∈ D ln ⁡ σ ( x ^ u i j ) λ ∣ ∣ Θ ∣ ∣ 2 L_{\text{BPR}} - \sum_{(u, i, j) \in D} \ln \sigma(\hat{x}_{uij}) \lambda ||\Theta||^2 LBPR​−(u,i,j)∈D∑​lnσ(x^ui…

Java 核心--泛型枚举

作者:IvanCodes 发布时间:2025年4月30日🤓 专栏:Java教程 各位 CSDN伙伴们,大家好!👋 写了那么多代码,有没有遇到过这样的“惊喜”:满心欢喜地从 ArrayList 里取出数据…

新能源行业供应链规划及集成计划报告(95页PPT)(文末有下载方式)

资料解读:《数字化供应链规划及集成计划现状评估报告》 详细资料请看本解读文章的最后内容。 该报告围绕新能源行业 XX 企业供应链展开,全面评估其现状,剖析存在的问题,并提出改进方向和关键举措,旨在提升供应链竞争力…

Centos 7 yum配置出现一下报错:

One of the configured repositories failed (CentOS-$releaserver-Base), and yum doesnt have enough cached data to continue. At this point the only safe thing yum can do is fail. There are a few ways to work "fix" this: 1.解决CentOS Yum Repositor…

Redis 常见问题深度剖析与全方位解决方案指南

Redis 是一款广泛使用的开源内存数据库,在实际应用中常会遇到以下一些常见问题: 1.内存占用问题 问题描述:随着数据量的不断增加,Redis 占用的内存可能会超出预期,导致服务器内存不足,影响系统的稳定性和…