You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET调用SQL Server存储过程传多参数查询日期间数据无结果

VB.NET调用SQL Server存储过程传筛选参数无返回数据修复方案

核心问题点

  • 异常被完全吞服,无法定位真实错误:现有Catch块直接将DataSet赋值为Nothing,无任何错误日志,所有执行报错都会被前端识别为「无数据」,无法区分是真无匹配数据还是代码执行出错。
  • AddWithValue隐式类型推断导致参数类型不匹配(根因):所有参数通过AddWithValue传入时未显式指定SQL类型、长度:
    • 方法入参中日期为String类型,直接传给存储过程的datetime类型参数易出现格式解析偏差
    • 纯数字格式的字符串参数会被AddWithValue自动推断为int类型,和存储过程定义的nvarchar(60)类型不匹配,查询时发生隐式类型转换,要么直接报错(被吞掉),要么无法匹配到nvarchar类型存储的字段值。这也是SSMS直接传参能查到、程序传参查不到的核心原因——SSMS传入的字符串常量默认是nvarchar类型,和字段类型一致。
  • 存储过程WHERE条件存在歧义:RegistrationNo = ISNULL(@regNo, cv.RegistrationNo)未给字段加表别名,关联表存在同名字段时会出现解析错误;同时LEFT JOIN后直接在WHERE中写关联表的等值判断,部分场景会将LEFT JOIN强制转为INNER JOIN,过滤掉关联无结果的记录。
  • 参数判断逻辑重复:存储过程和代码端未统一空值/默认值(比如参数为'0'时设为NULL)的判断规则,易出现逻辑不一致。

修复后代码

VB.NET 端代码

Public Shared Function SearchRoboCallByDate(datefrom As DateTime, dateto As DateTime, customerNo As String, regNo As String, terminalNo As String) As DataSet
    Dim ds As New DataSet()
    ' Using语法自动释放数据库连接、命令对象资源,避免资源泄漏
    Using conn As New SqlConnection(ConfigurationManager.ConnectionStrings("SQLConnString").ConnectionString)
        Using cmd As New SqlCommand("sp_getRoboAlarmDetailByDate", conn)
            cmd.CommandType = CommandType.StoredProcedure
            cmd.CommandTimeout = 600

            ' 显式指定每个参数的类型、长度,完全弃用AddWithValue避免隐式类型问题
            cmd.Parameters.Add("@datefrom", SqlDbType.DateTime).Value = datefrom
            cmd.Parameters.Add("@dateto", SqlDbType.DateTime).Value = dateto

            ' 统一在代码端处理空值、默认值"0"的逻辑,和存储过程职责拆分
            Dim pCustomerNo As SqlParameter = cmd.Parameters.Add("@customerNo", SqlDbType.NVarChar, 60)
            pCustomerNo.Value = If(String.IsNullOrWhiteSpace(customerNo) OrElse customerNo.Trim() = "0", DBNull.Value, customerNo.Trim())

            Dim pRegNo As SqlParameter = cmd.Parameters.Add("@regNo", SqlDbType.NVarChar, 60)
            pRegNo.Value = If(String.IsNullOrWhiteSpace(regNo) OrElse regNo.Trim() = "0", DBNull.Value, regNo.Trim())

            Dim pTerminalNo As SqlParameter = cmd.Parameters.Add("@TerminalNo", SqlDbType.NVarChar, 60)
            pTerminalNo.Value = If(String.IsNullOrWhiteSpace(terminalNo) OrElse terminalNo.Trim() = "0", DBNull.Value, terminalNo.Trim())

            Dim adapter As New SqlDataAdapter(cmd)
            Try
                adapter.Fill(ds)
            Catch ex As Exception
                ' 生产环境必须在这里加错误日志记录ex的完整信息,禁止直接吞异常
                ds = Nothing
                Throw ' 开发阶段直接抛出错误方便定位问题
            End Try
        End Using
    End Using
    Return ds
End Function

SQL Server 存储过程代码

ALTER PROCEDURE sp_getRoboAlarmDetailByDate
    @datefrom datetime = NULL,
    @dateto datetime = NULL,
    @customerNo as nvarchar(60) = NULL,
    @regNo as nvarchar(60) = NULL,
    @TerminalNo as nvarchar(60) = NULL
AS
BEGIN
    SET NOCOUNT ON; -- 关闭影响行数返回,减少网络传输开销

    SELECT
        ID = 0,  
        rda.RCLogID, 
        rda.VehicleID,
        cv.RegistrationNo, 
        rda.TerminalNo, 
        rda.PollID,
        rda.PacketNo, 
        rda.TableNo,
        rda.ServerID,
        rda.ServerName,
        rda.isCallSuccessful,
        rda.Remarks,
        rda.CreatedOn, 
        c.CustomerID, 
        c.CustomerNo
    FROM
        RoboCalls_DefuseAlarms_Log rda
    LEFT JOIN
        CustomersVehicles cv ON cv.VehicleId = rda.VehicleID 
    LEFT JOIN
        Customers c ON c.CustomerID = cv.CustomerId
    WHERE
        rda.CreatedOn BETWEEN @datefrom AND @dateto 
        -- 所有字段加表别名避免歧义,用参数空值判断写法替代ISNULL,更利于索引命中
        AND (@customerNo IS NULL OR c.CustomerNo = @customerNo)  
        AND (@regNo IS NULL OR cv.RegistrationNo = @regNo) 
        AND (@TerminalNo IS NULL OR rda.TerminalNo = @TerminalNo)
END

注意事项

  • 方法入口的日期参数必须改为DateTime类型,不要用String接收日期,从源头避免不同服务器区域格式导致的日期解析错误
  • 传入字符串参数前统一做Trim处理,避免前端传入的前后空格导致字段匹配失败
  • 禁止在数据访问层直接吞掉所有异常,必须保留错误日志,否则后续出现问题完全无法定位

内容的提问来源于stack exchange,提问作者Sanaullah Shahbaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 12:01:12