在近期的工作中,发现了这么一个问题,在某一搜索页面,需要同时查询多种订单类型,但在页面中未选择任何订单类型,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的数据