SqlSugarCore.Kdbndp 执行存储过程时不抛出 SQL 错误异常 返回

SqlSugar 沟通中
1 261
该叫什么 Henry 发布于1个月前
悬赏:0 飞吻

【问题描述】


在使用 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 fate sta VIP0
    1个月前

    1、人大金仓 版本号号和模式是什么  ?

    2、sqlsugar是最新版本吗?

    3、程序中设置databasemodel了吗?

    0 回复