如何重写SQL WHERE子句避免重复书写一致的查询条件
WHERE子句重写优化方案
你当前的WHERE子句两个分支仅I.Type取值不同,其余筛选条件完全重复,可以直接提取公共条件,将类型判断合并为IN匹配,逻辑和原查询完全等价,同时消除重复代码。
优化后WHERE子句
WHERE IH.ItemDetailID = '{itemDetailId}' AND Ih.Action NOT IN ('Access', 'AddToFavourites', 'ItemDefaultFavouriteChanged', 'RemoveFromFavourites', 'View') AND I.Type IN ('Document', 'ProcessMap')
原写法依赖SQL中
AND运算符优先级高于OR的规则实现筛选,后续维护调整条件时如果漏加括号很容易触发逻辑错误,改写后的写法逻辑更直观,不存在这类隐患。
额外优化建议
你当前使用C#字符串插值直接拼接参数到SQL语句中,即使Guid类型本身格式固定注入风险较低,依然不推荐这种写法:
- 无法复用数据库的查询执行计划,性能更差
- 后续如果参数类型更换为字符串等类型,很容易引入SQL注入漏洞
建议改用参数化查询,调整后的完整方法如下:
private static string HistoryQuery(Guid itemDetailId) { var sql = @" Select IH.ItemDetailID, i.Type, v.Number, v.Title, V.MajorRevisionNumber AS RevisionNumber, Ih.Action, Ih.ActionedBy, Ih.ActionedDate, Ih.Comment, iwft.Type as TaskType, iwft.StartDate, iwft.CompletedDate, Iwft.Status, Iwft.Outcome, Iwfta.ActionedBy as TaskActionedBy, Iwfta.ActionDate, Iwfta.Action as TaskAction, Iwfta.Comment as TaskComment, lid.URL From ItemView v Join ItemHistory Ih On Ih.ItemDetailID = v.ItemDetailId Join Item i On i.ItemID = v.ItemId Left Outer join ItemWorkflowTask Iwft On Iwft.ItemDetailID = v.ItemDetailId Left outer Join ItemWorkflowTaskAction Iwfta On Iwfta.ItemWorkflowTaskID = Iwft.ItemWorkflowTaskID Left outer Join DocumentItemDetail did ON did.ItemDetailID = Ih.ItemDetailID Left outer Join ItemDetail id ON id.ItemID = did.LinkItemID Left outer JOIN LinkItemDetail lid ON lid.ItemDetailID = id.ItemDetailID Where IH.ItemDetailID = @ItemDetailId AND Ih.Action NOT IN ('Access', 'AddToFavourites', 'ItemDefaultFavouriteChanged', 'RemoveFromFavourites', 'View') AND I.Type IN ('Document', 'ProcessMap')"; return sql; }
实际执行SQL时,给数据库命令对象添加@ItemDetailId参数,值传入方法入参itemDetailId即可。
内容的提问来源于stack exchange,提问作者lross15
相关产品推荐
相关产品推荐

