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

SQL Server 2008中NVARCHAR拼接时ISNULL替换值被截断问题求助

问题描述

现有存储过程中包含一段拼接默认WHERE子句的NVARCHAR代码:

DECLARE @DEFAULT_WHERE NVARCHAR(MAX)
SET @DEFAULT_WHERE = N'RTRIM(LTRIM(DD.CODIGO)) = '  +isnull(''''+@ID_CODIGODENUNCIA+'''',   N'LTRIM(RTRIM(dd.CODIGO))') +' AND 
                       RTRIM(LTRIM(TI.ID)) = '      +isnull(''''+@ID_INGRESO+'''',          'LTRIM(RTRIM(ti.ID))')     +' AND 
                       RTRIM(LTRIM(TD.ID)) = '      +isnull(''''+@ID_DELITO+'''',           'LTRIM(RTRIM(td.ID))')     +' AND
                       RTRIM(LTRIM(AD.ID)) = '      +isnull(''''+@ID_LOCATIZACION+'''',     'LTRIM(RTRIM(ad.ID))')     +' AND
                       RTRIM(LTRIM(EF.ID)) = '      +isnull(''''+@ID_FASE+'''',             'LTRIM(RTRIM(ef.ID))')     +' AND
                       RTRIM(LTRIM(EE.ID)) = '      +isnull(''''+@ID_ESTADO+'''',           'LTRIM(RTRIM(ee.ID))')     +' AND
                       RTRIM(LTRIM(EA.ID)) = '      +isnull(''''+@ESTADO_ACTIVIDAD+'''',    'LTRIM(RTRIM(ea.ID))')     +' AND
                       RTRIM(LTRIM(TR.ID)) = '      +isnull(''''+@ID_RECEPCION+'''',        'LTRIM(RTRIM(tr.ID))')     +' AND
                       RTRIM(LTRIM(SU.ID)) = '      +isnull(''''+@USUARIO_CREACION+'''',    'LTRIM(RTRIM(su.ID))')

逻辑为:若参数未设置,则使用字段自身的LTRIM(RTRIM())作为默认匹配条件。但当所有参数均为空时,生成的@DEFAULT_WHERE出现字符串截断:

RTRIM(LTRIM(DD.CODIGO)) = LTRIM(RTRIM(
AND RTRIM(LTRIM(TI.ID)) = LTRIM(RTRIM(ti.ID))
AND RTRIM(LTRIM(TD.ID)) = LTRIM(RTRIM(td.ID))
AND RTRIM(LTRIM(AD.ID)) = LTRIM(RTRIM(ad.ID))
AND RTRIM(LTRIM(EF.ID)) = LTRIM(RTRIM(ef.ID))
AND RTRIM(LTRIM(EE.ID)) = LTRIM(RTRIM(ee.ID))
AND RTRIM(LTRIM(EA.ID)) = LTRIM(RTRIM(ea.ID))
AND RTRIM(LTRIM(TR.ID)) = LTRIM(RTRIM(tr.ID))
AND RTRIM(LTRIM(SU.ID)) = LTRIM(RTRIM(su.ID

首行丢失dd.CODIGO)),末行丢失))。移除LTRIM和RTRIM仅保留字段名时,截断问题消失,但业务需要保留字符串修剪功能,需改写这段拼接代码。

解决方案

可以通过以下方式改写代码,避免截断问题:

DECLARE @DEFAULT_WHERE NVARCHAR(MAX)
SET @DEFAULT_WHERE = CONCAT(
    N'RTRIM(LTRIM(DD.CODIGO)) = ', ISNULL(N'''' + @ID_CODIGODENUNCIA + N'''', N'LTRIM(RTRIM(DD.CODIGO))'), N' AND ',
    N'RTRIM(LTRIM(TI.ID)) = ', ISNULL(N'''' + @ID_INGRESO + N'''', N'LTRIM(RTRIM(TI.ID))'), N' AND ',
    N'RTRIM(LTRIM(TD.ID)) = ', ISNULL(N'''' + @ID_DELITO + N'''', N'LTRIM(RTRIM(TD.ID))'), N' AND ',
    N'RTRIM(LTRIM(AD.ID)) = ', ISNULL(N'''' + @ID_LOCATIZACION + N'''', N'LTRIM(RTRIM(AD.ID))'), N' AND ',
    N'RTRIM(LTRIM(EF.ID)) = ', ISNULL(N'''' + @ID_FASE + N'''', N'LTRIM(RTRIM(EF.ID))'), N' AND ',
    N'RTRIM(LTRIM(EE.ID)) = ', ISNULL(N'''' + @ID_ESTADO + N'''', N'LTRIM(RTRIM(EE.ID))'), N' AND ',
    N'RTRIM(LTRIM(EA.ID)) = ', ISNULL(N'''' + @ESTADO_ACTIVIDAD + N'''', N'LTRIM(RTRIM(EA.ID))'), N' AND ',
    N'RTRIM(LTRIM(TR.ID)) = ', ISNULL(N'''' + @ID_RECEPCION + N'''', N'LTRIM(RTRIM(TR.ID))'), N' AND ',
    N'RTRIM(LTRIM(SU.ID)) = ', ISNULL(N'''' + @USUARIO_CREACION + N'''', N'LTRIM(RTRIM(SU.ID))')
)

改写说明:

  1. 使用CONCAT替代+拼接:CONCAT函数会自动处理Unicode字符串类型转换,避免因+拼接时的隐式类型转换导致的字符串长度计算错误和截断。
  2. 统一字符串前缀N:确保所有字符串常量(包括拼接的引号和默认条件)都带有N前缀,强制为NVARCHAR类型,避免VARCHAR与NVARCHAR混合拼接时的长度损耗。
  3. 可选:保留换行格式:若需要保留原代码的换行排版,可在每个AND后添加NCHAR(13)+NCHAR(10),示例:
    SET @DEFAULT_WHERE = CONCAT(
        N'RTRIM(LTRIM(DD.CODIGO)) = ', ISNULL(N'''' + @ID_CODIGODENUNCIA + N'''', N'LTRIM(RTRIM(DD.CODIGO))'), N' AND ', NCHAR(13), NCHAR(10),
        N'RTRIM(LTRIM(TI.ID)) = ', ISNULL(N'''' + @ID_INGRESO + N'''', N'LTRIM(RTRIM(TI.ID))'), N' AND ', NCHAR(13), NCHAR(10),
        -- 其余条件同理
        N'RTRIM(LTRIM(SU.ID)) = ', ISNULL(N'''' + @USUARIO_CREACION + N'''', N'LTRIM(RTRIM(SU.ID))')
    )
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:51:48