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

如何修改存储过程WHERE子句:@PackageId非空时切换AND/OR逻辑

问题

如何修改存储过程中的如下代码片段,使得仅当@PackageId不为空时,将pd.PackageID = @PackageId OR替换为pd.PackageID = @PackageId AND?

原代码片段:

pd.PackageID  = @PackageId OR
        FREETEXT(o.ObjectNumber, @SearchText)  OR
        FREETEXT(o.DisplayLocation, @SearchText)  OR
        FREETEXT(o.SearchTitle, @SearchText)  OR
        FREETEXT(o.WebKeyword, @SearchText)  OR

需求场景:

  1. 当@PackageId和@SearchText均有值时,代码应变为:
pd.PackageID  = @PackageId AND
    FREETEXT(o.ObjectNumber, @SearchText)  OR
    FREETEXT(o.DisplayLocation, @SearchText)  OR
    FREETEXT(o.SearchTitle, @SearchText)  OR
    FREETEXT(o.WebKeyword, @SearchText)  OR
  1. 当仅@PackageId有值时,只需保留:
pd.PackageID  = @PackageId
解决方案

方案一:动态SQL拼接(逻辑清晰,推荐)

通过动态生成WHERE子句,精准匹配不同参数组合的需求:

DECLARE @WhereClause NVARCHAR(MAX) = ''
DECLARE @MainQuery NVARCHAR(MAX) = 'SELECT [你的查询字段] FROM [你的表名] pd JOIN [关联表] o ON [关联条件]' -- 替换为实际查询主体

-- 处理PackageId条件
IF @PackageId IS NOT NULL
BEGIN
    SET @WhereClause = @WhereClause + 'pd.PackageID = @PackageId'
END

-- 处理SearchText条件
IF @SearchText IS NOT NULL
BEGIN
    DECLARE @FreeTextConditions NVARCHAR(MAX) = 
        'FREETEXT(o.ObjectNumber, @SearchText) OR ' +
        'FREETEXT(o.DisplayLocation, @SearchText) OR ' +
        'FREETEXT(o.SearchTitle, @SearchText) OR ' +
        'FREETEXT(o.WebKeyword, @SearchText)'

    IF @WhereClause <> ''
    BEGIN
        -- 已有PackageId条件,用AND关联FREETEXT条件组
        SET @WhereClause = @WhereClause + ' AND (' + @FreeTextConditions + ')'
    END
    ELSE
    BEGIN
        SET @WhereClause = @FreeTextConditions
    END
END

-- 拼接最终执行SQL
IF @WhereClause <> ''
BEGIN
    SET @MainQuery = @MainQuery + ' WHERE ' + @WhereClause
END

-- 执行查询,传入参数
EXEC sp_executesql @MainQuery, N'@PackageId INT, @SearchText NVARCHAR(MAX)', @PackageId, @SearchText

逻辑说明:

  • 仅@PackageId有值时,WHERE子句仅保留pd.PackageID = @PackageId
  • 两个参数都有值时,PackageId条件与FREETEXT条件组用AND连接,FREETEXT内部保持OR逻辑
  • 仅@SearchText有值时,直接使用所有FREETEXT的OR条件

方案二:静态条件拼接(无需动态SQL)

如果不想使用动态SQL,可通过参数判断实现条件分支,建议添加OPTION(RECOMPILE)优化执行计划:

SELECT [你的查询字段]
FROM [你的表名] pd
JOIN [关联表] o ON [关联条件]
WHERE 
    -- 当@PackageId不为空时必须匹配,为空时跳过该条件
    (@PackageId IS NULL OR pd.PackageID = @PackageId)
    AND
    -- 当@SearchText不为空时匹配任意FREETEXT,为空时跳过
    (@SearchText IS NULL OR 
        FREETEXT(o.ObjectNumber, @SearchText) OR
        FREETEXT(o.DisplayLocation, @SearchText) OR
        FREETEXT(o.SearchTitle, @SearchText) OR
        FREETEXT(o.WebKeyword, @SearchText)
    )
OPTION(RECOMPILE) -- 让优化器根据实际参数生成最优计划

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:53:22