我想这样做
SELECT *
FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND ((@booked_in IS NULL) OR ( booked_in = @booked_in))
AND ((@depot_assigned IS NULL) OR ( IF @depot_assigned = 'Y' depot_code <> ' ' ELSE depot_code = ' ') )
我确信你们都可以猜到OR(IF @dede_assigned等)位失败。
我该如何做这样的事情,或者我必须根据@depot_assigned参数的值将它作为两个单独的select语句来完成。
答案 0 :(得分:7)
SELECT
*
FROM
sales_order_header
WHERE
order_reference LIKE @order_reference + '%' AND
((@booked_in IS NULL) OR ( booked_in = @booked_in)) AND
((@depot_assigned IS NULL) OR
( @depot_assigned = 'Y' AND depot_code <> ' ' ) OR
( @depot_assigned <> 'Y' AND depot_code = ' ') )
答案 1 :(得分:3)
您正在寻找T-SQL CASE语句。对以下代码的修改应该适合您:
SELECT
*
FROM
sales_order_header
WHERE
order_reference LIKE @order_reference + '%' AND
((@booked_in IS NULL) OR ( booked_in = @booked_in)) AND
((@depot_assigned IS NULL) OR (CASE WHEN @depot_assigned = 'Y' THEN depot_code <> ' ' ELSE depot_code = ' ' END) )
答案 2 :(得分:0)
当您构建类似于您尝试的查询时,查询优化器必须创建一个计划以适合参数的任何值。这将导致最糟糕的计划。因此,即使您提出了正确的表达式(使用CASE),由于OR条件相矛盾,查询的执行性也会非常差。
将IF分成SQL条件,并对每种情况使用不同的查询:
IF @booked_in IS NULL and @depot_assigned IS NULL
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
ELSE IF @depot_assigned IS NULL
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND booked_in = @booked_in
ELSE IF @booked_in IS NULL AND @depot_code='Y'
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND depot_code <> ' '
ELSE IF IF @booked_in IS NULL AND @depot_code<>'Y'
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND depot_code = ' '
ELSE IF @depot_code = 'Y'
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND booked_in = @booked_in
AND depot_code <> ' '
ELSE
SELECT * FROM sales_order_header
WHERE order_reference LIKE @order_reference + '%'
AND booked_in = @booked_in
AND depot_code = ' '
尽管有明显的不雅和缺乏优雅,但这是最好的方法。它的主要缺点是可维护性问题,并且在使用动态SQL构建查询时有一个可行的替代方法。
最终,IF条件的复杂性是代码味道,您的数据访问API会执行太多应该是单独的API入口点的事情。
答案 3 :(得分:0)
SELECT * FROM sales_order_header
WHERE
order_reference LIKE @order_reference + '%'
AND
booked_in = ISNULL(@booked_in,booked_in)
AND
CASE
WHEN @depot_assigned IS NULL THEN 1
WHEN @depot_assigned = 'Y' AND depot_code <> ' ' THEN 1
WHEN @depot_assigned <> 'Y' AND depot_code = ' ' THEN 1
ELSE 0
END = 1
编辑:与其他一些答案类似。稍微简化一下。