记一次,SQL中使用IN关键字时,因空数组替换参数导致了SQL语法错误

场景


  在近期的工作中,发现了这么一个问题,在某一搜索页面,需要同时查询多种订单类型,但在页面中未选择任何订单类型,API通过UI端传来的空订单类型数组进行查询时,抛出了SQL的语法错误

  原SQL : 

SELECT * FROM dbo.order WHERE type IN @OrderType

  正常情况下,在UI端选入了订单类型时,SQL会被框架替换成

SELECT * FROM dbo.order WHERE type IN (1,2,3)

  非正常情况下,在UI端未选入订单类型时,SQL会被框架替换成

SELECT * FROM dbo.order WHERE type IN ()

  但总所周知,这种情况下,SQL是有语法错误的,执行会报错: Incorrect syntax near ')'.

如何解决?


  1.从业务层考虑

    对于这种问题,空数组的查询,是否是不合法的请求,需要在业务层取拦截,但这个方案因项目中大面积存在这个问题,每个方法都去修改的话修改量和工作量比较大,所以不太适合这次的修改

  2.从底层框架考虑

    那么通过在执行SQL替换SQL Paramater参数时进行思考与分析

    通过下列SQL执行过程分析发现

SELECT * FROM dbo.order WHERE type IN @OrderType

    框架会通过传入的数组参数,对于需要替换Parameter进行拆分,及传入的OrderType数组假设为1,2,3

    则@OrderType参数会被拆分为@OrderType0,@OrderType1,@OrderType2,并且他们的值也会对应为1,2,3,并且此时的SQL语句也会转换成

SELECT * FROM dbo.order WHERE type IN (@OrderType0,@OrderType1,@OrderType2)

    最后会通过预编译传参,执行最终SQL

SELECT * FROM dbo.order WHERE type IN (1,2,3)

    所以在参数进行拆分时,如果是空数组,此时的SQL语句就会转换成

SELECT * FROM dbo.order WHERE type IN ()

    这时,这是个错误的SQL,需要在底层代码进行判断了,如果是空数组时,只需要将SQL转换成

SELECT * FROM dbo,order WHERE type IN (NULL)

    便能避免报错,且能符合业务,并且从SQL中虽看到的查询条件是type = NULL,但实际是不会查询出type = NULL的数据

 

posted @ 2022-03-29 15:35  TheBestTxt  阅读(267)  评论(0编辑  收藏  举报