SqlSugarCore.Kdbndp 执行存储过程时不抛出 SQL 错误异常 返回
Henry 发布于1个月前
【问题描述】
在使用 SqlSugarCore.Kdbndp 包(基于 Kdbndp 驱动)执行 KingBase 存储过程时,发现一个严重问题:当存储过程内部发生 SQL 错误时,SqlSugar 不会抛出异常,导致错误被静默忽略。
【环境信息】
- SqlSugarCore.Kdbndp 版本:9.3.7.1032
- KingBase 版本:V009R004C012
- .NET 版本:.NET 8.0
- 操作系统:Windows 11
【完整复现步骤】
第一步:创建测试表和存储过程
-- 1. 创建测试表
CREATE TABLE test_table (
id INT PRIMARY KEY,
name VARCHAR(100),
value INT
);
INSERT INTO test_table VALUES (1, 'test', 100);
-- 2. 创建一个有错误的存储过程(查询不存在的字段)
CREATE OR REPLACE PROCEDURE test_error_proc(p_id INT)
AS
BEGIN
-- 故意查询不存在的字段,应该报错
SELECT non_existent_column FROM test_table WHERE id = p_id;
END;
-- 3. 创建一个正常的存储过程(用于对比)
CREATE OR REPLACE PROCEDURE test_normal_proc(p_id INT)
AS
BEGIN
SELECT id, name, value FROM test_table WHERE id = p_id;
END;
第二步:C# 测试代码
using SqlSugar;
using System;
namespace KdbndpErrorTest
{
class Program
{
static void Main(string[] args)
{
// 配置 SqlSugar 连接
var db = new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Server=127.0.0.1;Port=54321;Database=test;User Id=system;Password=123456;",
DbType = DbType.Kdbndp, // 或 DbType.KingbaseES
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
});
Console.WriteLine("=== 测试 1:调用正常的存储过程 ===");
TestNormalProcedure(db);
Console.WriteLine("\n=== 测试 2:调用有错误的存储过程(预期应该抛异常,实际不会)===");
TestErrorProcedure(db);
Console.WriteLine("\n=== 测试 3:使用原生 Kdbndp 驱动测试 ===");
TestWithRawKdbndp();
Console.WriteLine("\n测试完成。按任意键退出...");
Console.ReadKey();
}
// 测试正常的存储过程
static void TestNormalProcedure(SqlSugarClient db)
{
try
{
var result = db.Ado.UseStoredProcedure()
.ExecuteCommand("test_normal_proc", new { p_id = 1 });
Console.WriteLine($"✅ 正常存储过程执行成功,返回值:{result}");
}
catch (Exception ex)
{
Console.WriteLine($"❌ 捕获异常:{ex.GetType().Name} - {ex.Message}");
}
}
// 测试有错误的存储过程
static void TestErrorProcedure(SqlSugarClient db)
{
try
{
var result = db.Ado.UseStoredProcedure()
.ExecuteCommand("test_error_proc", new { p_id = 1 });
// ❌ 不应该到达这里!应该在上面抛出异常
Console.WriteLine($"❌❌❌ BUG:存储过程静默执行,返回值:{result}");
Console.WriteLine(" 预期行为:应该抛出 SqlSugarException 或 KdbndpException");
Console.WriteLine(" 实际行为:没有抛出任何异常!");
}
catch (Exception ex)
{
// ✅ 正确的行为:应该进入这里
Console.WriteLine($"✅ 正确捕获异常:{ex.GetType().Name}");
Console.WriteLine($" 异常信息:{ex.Message}");
}
}
// 使用原生 Kdbndp 驱动测试(排除 SqlSugar 的问题)
static void TestWithRawKdbndp()
{
try
{
using var conn = new Kdbndp.KdbndpConnection(
"Server=127.0.0.1;Port=54321;Database=test;User Id=system;Password=123456;");
conn.Open();
using var cmd = new Kdbndp.KdbndpCommand("test_error_proc", conn)
{
CommandType = System.Data.CommandType.StoredProcedure
};
cmd.Parameters.AddWithValue("p_id", 1);
cmd.ExecuteNonQuery();
// ❌ 不应该到达这里
Console.WriteLine("❌❌❌ BUG:原生 Kdbndp 驱动也不抛异常!");
Console.WriteLine(" 说明这是 Kdbndp 驱动层的问题,不是 SqlSugar 的问题");
}
catch (Exception ex)
{
Console.WriteLine($"✅ 原生驱动正确抛出异常:{ex.GetType().Name}");
Console.WriteLine($" 异常信息:{ex.Message}");
}
}
}
}
第三步:运行测试
预期输出:
=== 测试 1:调用正常的存储过程 ===
✅ 正常存储过程执行成功,返回值:1
=== 测试 2:调用有错误的存储过程(预期应该抛异常,实际不会)===
✅ 正确捕获异常:KdbndpException
异常信息:column "non_existent_column" does not exist
=== 测试 3:使用原生 Kdbndp 驱动测试 ===
✅ 原生驱动正确抛出异常:KdbndpException
异常信息:column "non_existent_column" does not exist
实际输出:
=== 测试 1:调用正常的存储过程 ===
✅ 正常存储过程执行成功,返回值:1
=== 测试 2:调用有错误的存储过程(预期应该抛异常,实际不会)===
❌❌❌ BUG:存储过程静默执行,返回值:0
预期行为:应该抛出 SqlSugarException 或 KdbndpException
实际行为:没有抛出任何异常!
=== 测试 3:使用原生 Kdbndp 驱动测试 ===
❌❌❌ BUG:原生 Kdbndp 驱动也不抛异常!
说明这是 Kdbndp 驱动层的问题,不是 SqlSugar 的问题
【问题分析】
通过测试 3 可以确认:这是底层 Kdbndp 驱动的问题,不是 SqlSugar 的问题。
但由于 SqlSugar 是 KingBase 用户的主要 ORM 选择,建议:
1. SqlSugar 团队向 KingBase 官方反馈此问题
2. 或者在 SqlSugar 中增加额外的错误检测机制作为临时方案
【影响范围】
- 影响所有通过 SqlSugar 调用 KingBase 存储过程的场景
- 数据库 Schema 变更时无法及时发现存储过程兼容性问题
- 生产环境难以排查业务逻辑错误
- 可能导致数据不一致或业务流程异常
【对比其他数据库】
数据库 | SqlSugar DbType | 存储过程错误处理
---|---|---
SQL Server | DbType.SqlServer | ✅ 正确抛出 SqlException
MySQL | DbType.MySql | ✅ 正确抛出 MySqlException
PostgreSQL | DbType.PostgreSQL | ✅ 正确抛出 NpgsqlException
KingBase | DbType.Kdbndp | ❌ 不抛异常(驱动层问题)
【建议修复方案】
1. 短期方案(SqlSugar 层):
- 在存储过程执行后,通过额外的 SQL 查询检查是否有错误
- 例如:SELECT COUNT(*) FROM pg_stat_activity WHERE state = 'idle in transaction (aborted)'
2. 长期方案(需要 KingBase 官方修复):
- 向 KingBase 官方提交 Issue(Kdbndp 驱动仓库)
- 修复底层驱动的异常抛出机制
感谢 SqlSugar 团队的关注和支持!如有需要,我可以提供更多测试数据或协助排查问题。
热忱回答(1)
-
fate sta VIP0
1个月前1、人大金仓 版本号号和模式是什么 ?
2、sqlsugar是最新版本吗?
3、程序中设置databasemodel了吗?
0 回复