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

SQL Server存储过程返回值在C#中显示为NULL的问题排查

问题分析:带翻译的存储过程在C#中返回NULL而非指定文本

我有两个从SQL Server返回数据到C#的存储过程,逻辑几乎一致,区别在于其中一个多了翻译参数,用来从翻译表获取参考表的对应翻译内容。

基础存储过程

ALTER PROCEDURE [dbo].[BasicOutput]
@StartDate DATETIME2,
@EndDate DATETIME2,
@StartIndex INT,
@RowSize INT
AS
BEGIN
    DECLARE @AreaCode NVARCHAR(20) = 'TEST' 

    SELECT * FROM
    (
        SELECT ROW_NUMBER() OVER(ORDER BY d.[Date] ASC) AS RowNum, ISNULL(la.[Name], 'Not Specified') AS LA, ISNULL(ag.AgeGroup5yr, 'Not Specified') AS AgeGroupId, d.[Year], d.QuarterNameShort AS [Quarter], d.FinancialYearName + ' ' + d.FinancialQuarterNameShort AS FinancialYearAndQuarter, t.TimeBucket, d.DayOfWeekUK
        FROM dbo.TestData fa
        INNER JOIN dbo.DimDate d
        ON fa.AttendanceDateId = d.DateKey
        INNER JOIN dbo.DimTime t
        ON fa.AttendanceTimeId = t.TimeKey
        LEFT JOIN REF_LocalAuthority la
        ON fa.LA = la.LowerTierLAcode
        LEFT JOIN REF_AgeGroup ag
        ON fa.AgeGroupId = ag.ID
        WHERE d.[Date] >= @StartDate AND d.[Date] <= @EndDate
        AND (
            la.CtyCode = @AreaCode
            OR sc.CTYcode = @AreaCode
        )
    )a
    WHERE RowNum > @StartIndex AND RowNum <= (@StartIndex + @RowSize)
END

带翻译的存储过程

ALTER PROCEDURE [dbo].[OutputWithTranslation]
@StartDate DATETIME2,
@EndDate DATETIME2,
@StartIndex INT,
@RowSize INT,
@TranslateLanguageCode NVARCHAR(10) = NULL
AS
BEGIN
    DECLARE @LanguageId INT = NULL
    DECLARE @NotSpecifiedText NVARCHAR(20) = 'Not Specified'
    IF(@TranslateLanguageCode IS NOT NULL)
    BEGIN
        SET @LanguageId = (SELECT Id FROM TranslationLanguage WHERE LanguageCode = @TranslateLanguageCode);
        SET @NotSpecifiedText = (SELECT TranslationText FROM REF_GenericResponse gr LEFT JOIN REF_GenericResponse_Translation grtran ON gr.Id = grtran.ResponseId WHERE gr.[Text] = @NotSpecifiedText AND grtran.LanguageId = @LanguageId)      
    END
    DECLARE @AreaCode NVARCHAR(20) = 'TEST' 

    SELECT * FROM
    (
        SELECT ROW_NUMBER() OVER(ORDER BY d.[Date] ASC) AS RowNum, COALESCE(latran.TranslationText, la.[Name], @NotSpecifiedText) AS LA, ISNULL(ag.AgeGroup5yr, @NotSpecifiedText) AS AgeGroupId, d.[Year], d.QuarterNameShort AS [Quarter], d.FinancialYearName + ' ' + d.FinancialQuarterNameShort AS FinancialYearAndQuarter, t.TimeBucket, d.DayOfWeekUK
        FROM dbo.TestData fa
        INNER JOIN dbo.DimDate d
        ON fa.AttendanceDateId = d.DateKey
        INNER JOIN dbo.DimTime t
        ON fa.AttendanceTimeId = t.TimeKey
        LEFT JOIN REF_LocalAuthority la
        ON fa.LA = la.LowerTierLAcode

        LEFT JOIN REF_LocalAuthority_Translation latran
        ON la.ID = latran.LocalAuthorityId AND (@TranslateLanguageCode IS NOT NULL AND latran.LanguageId = @LanguageId)

        LEFT JOIN REF_AgeGroup ag
        ON fa.AgeGroupId = ag.ID

        WHERE d.[Date] >= @StartDate AND d.[Date] <= @EndDate
        AND (
        la.CtyCode = @AreaCode
        OR sc.CTYcode = @AreaCode
        )
    )a
    WHERE RowNum > @StartIndex AND RowNum <= (@StartIndex + @RowSize)
END

问题现象

在SQL Server中执行时,两个存储过程的输出都正常,NULL值会被正确替换为Not Specified或对应的翻译文本。但在C#代码中接收返回结果时,带翻译的存储过程里本该显示Not Specified的字段却变成了NULL。试过用嵌套ISNULL替换COALESCE,没用;但在基础存储过程里添加@NotSpecifiedText变量并使用COALESCE(NULL, la.[Name], @NotSpecifiedText)却能正常工作。


原因分析

核心问题是**@NotSpecifiedText变量可能被赋值为NULL**,导致最终的COALESCE/ISNULL兜底逻辑失效:

看带翻译的存储过程里的这段逻辑:

IF(@TranslateLanguageCode IS NOT NULL)
BEGIN
    SET @LanguageId = (SELECT Id FROM TranslationLanguage WHERE LanguageCode = @TranslateLanguageCode);
    SET @NotSpecifiedText = (SELECT TranslationText FROM REF_GenericResponse gr LEFT JOIN REF_GenericResponse_Translation grtran ON gr.Id = grtran.ResponseId WHERE gr.[Text] = @NotSpecifiedText AND grtran.LanguageId = @LanguageId)      
END

当@TranslateLanguageCode不为空,但查询REF_GenericResponse_Translation时找不到对应的翻译记录,@NotSpecifiedText就会被设为NULL。此时后续的COALESCE(latran.TranslationText, la.[Name], @NotSpecifiedText)会因为第三个参数是NULL,最终返回NULL。

而基础存储过程直接用字符串常量'Not Specified',不存在被覆盖为NULL的情况;你在基础存储过程测试时,@NotSpecifiedText是初始值'Not Specified',未被修改,所以正常工作。

另外注意:两个存储过程的WHERE子句里都用到了sc.CTYcode,但FROM子句中没有引入表sc,这会导致编译错误,建议检查是否遗漏了表连接。


解决方案

  1. 给@NotSpecifiedText的赋值语句添加ISNULL兜底,确保就算找不到翻译也不会变成NULL,同时查询条件用原始字符串常量避免变量覆盖问题:
IF(@TranslateLanguageCode IS NOT NULL)
BEGIN
    SET @LanguageId = (SELECT Id FROM TranslationLanguage WHERE LanguageCode = @TranslateLanguageCode);
    -- 用ISNULL兜底,查询条件用原始常量'Not Specified'
    SET @NotSpecifiedText = ISNULL(
        (SELECT TranslationText FROM REF_GenericResponse gr 
         LEFT JOIN REF_GenericResponse_Translation grtran ON gr.Id = grtran.ResponseId 
         WHERE gr.[Text] = 'Not Specified' AND grtran.LanguageId = @LanguageId),
        'Not Specified'
    )      
END
  1. 修复WHERE子句中未定义的sc表问题,补充对应的表连接或修正条件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:47:05