当前位置: 首页 > news >正文

sqlserver怎样动态执行存储过程,并且返回报错

存储过程1

USE [OM]
GO
/****** Object:  StoredProcedure [dbo].[procTranDemo2]    Script Date: 2025/6/24 19:20:23 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GOCREATE PROCEDURE [dbo].[procTranDemo2]@wo VARCHAR(255),@cartonId VARCHAR(255) OUTPUT
AS
DECLARE @sql VARCHAR(100);
DECLARE @errorMsg VARCHAR(4000);
DECLARE @SavePoint VARCHAR(32) = 'SP_' + CAST(@@SPID AS VARCHAR);
BEGIN
SET NOCOUNT ON; -- 禁用受影响行数的消息返回
SAVE TRANSACTION @SavePoint; 
BEGIN TRYPRINT @wo;--set @sql = 'delete from mes_zhiju_box where box_id = ''test'''--print @sql--exec(@sql)THROW 51000, '动态sql报错', 1;--select 'key1' as 'label_key', 'value1' as 'label_value'SET @cartonId = 'test0001';END TRY
BEGIN CATCHPRINT 'demo2';PRINT @@TRANCOUNT;SET @errorMsg = ERROR_MESSAGE();ROLLBACK TRANSACTION @SavePoint;-- 重新抛出原始错误(保留堆栈)THROW;
END CATCH
END

存储过程2

USE [OM]
GO
/****** Object:  StoredProcedure [dbo].[procTranDemo]    Script Date: 2025/6/24 19:20:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GOALTER PROCEDURE [dbo].[procTranDemo]@wo varchar(255),@cartonId VARCHAR(255) OUTPUT
AS
DECLARE @sql NVARCHAR(MAX);
DECLARE @errorMsg VARCHAR(4000);
DECLARE @errorCode INT;
BEGIN
SET NOCOUNT ON; -- 禁用受影响行数的消息返回
BEGIN TRY;BEGIN TRAN;DECLARE @paramDefinition NVARCHAR(500);DECLARE @procName VARCHAR(50) = 'procTranDemo2';SET @sql = N'DECLARE @innerError INT, @innerMessage VARCHAR(4000);BEGIN TRY-- 执行目标存储过程EXEC '+ @procName +'@wo = '''+ @wo +''',@cartonId = @cartonId OUTPUTEND TRYBEGIN CATCH-- 捕获存储过程内部异常SET @innerError = ERROR_NUMBER();SET @innerMessage = ERROR_MESSAGE();END CATCH;-- 传递错误信息到外层SELECT @errorCode = @innerError, @errorMsg = @innerMessage;';SET @paramDefinition = N'@cartonId VARCHAR(100) OUTPUT,@errorCode INT OUTPUT,@errorMsg VARCHAR(4000) OUTPUT';EXEC sp_executesql @sql,                       -- 动态SQL字符串@paramDefinition,                  -- 参数定义@cartonId = @cartonId OUTPUT, -- 绑定:动态参数 -> 外部变量@errorCode = @errorCode OUTPUT,@errorMsg = @errorMsg OUTPUT;IF(@errorCode IS NOT NULL OR @errorMsg IS NOT NULL)BEGIN-- 自定义错误处理(如记录日志)PRINT '存储过程内部错误: ' + COALESCE(@errorMsg, '未知错误');-- 重新抛出错误THROW 51000, @errorMsg, 1;END;IF(@@TRANCOUNT > 0)BEGINCOMMIT TRAN;END 
END TRY
BEGIN CATCHPRINT 'demo1';PRINT @@TRANCOUNT;IF(@@TRANCOUNT > 0)BEGINSET @errorMsg = ERROR_MESSAGE()ROLLBACK TRANSACTIONEND;-- 重新抛出原始错误(保留堆栈)THROW;
END CATCH
END

讲解

我们需要在存储过程2中动态调用存储过程1,这里面着重需要注意的是事务的管理,首先事务嵌套事务,当内部事务报错时,我们一般会执行回滚,那么一回滚就会连同外部的事务也一起回滚掉了,执行时就会报错。

所以我在存储过程1(内部)中使用了保存点回滚,而在存储过程2(外部)中使用了事务回滚。

还有THROW这个关键字的使用,你可以先记住它就是抛出异常、中断批处理。其余的你可以百度它的深层意思。

http://www.lryc.cn/news/574831.html

相关文章:

  • Java实现简易即时通讯系统
  • day41 打卡
  • 基于元学习的回归预测模型如何设计?
  • MySQL:深入总结锁机制
  • linux操作系统的软件架构分析
  • 战略调整频繁,如何快速重构项目组合
  • 原生策略与功耗方案参考
  • Android 开发问题:Wrong argument type for formatting argument ‘#2‘ in info_message
  • 马克思主义基本原理期末复习下
  • DVWA Brute Force漏洞深度分析与利用指南
  • iwebsec靶场sqli注入(2)
  • Vue3+Spring boot 前后端防抖增强方案
  • 学习记录:DAY33
  • 2025年渗透测试面试题总结-2025年HW(护网面试) 09(题目+回答)
  • HarmonyOS开发基础 --面向鸿蒙的TypeScript基础语法一文入门
  • 大模型本地部署,拥有属于自己的ChatGpt
  • 《仿盒马》app开发技术分享-- 兑换列表展示(68)
  • OSS安全合规实战:金融行业敏感数据加密+KMS自动轮转策略(满足等保2.0三级要求)
  • 如何使用MQTTX软件来进行MQTT协议的测试
  • # Python中等于号的使用
  • 逆向入门(7)汇编篇-mul指令的学习
  • DAY 41 简单CNN
  • 防御OSS Bucket泄露:RAM权限策略+日志审计+敏感数据扫描三重防护
  • DeepSeek智能总结 | 邓紫棋音乐版权纠纷核心梳理
  • 软件工程:从理论到实践,构建可靠软件的艺术与科学
  • 智慧家政数字化小程序开发:重构行业服务生态的创新引擎
  • 代码随想录|图论|01图论基础
  • 医药企业CMO研发管线管理专项介绍
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | MovieApp(电影卡片组件)
  • ArkTS与仓颉开发语言:鸿蒙编程的双子星