检查 WHERE 子句中的条件

Check condition in WHERE clause

我在 XML 映射中有以下动态 WHERE 条件,工作正常:

WHERE
    IncomingFlightId=#{flightId}
    <if test="screenFunction == 'MAIL'.toString()">
        and ContentCode = 'M'
    </if>
    <if test="screenFunction == 'CARGO'.toString()">
        and ContentCode Not IN('M')
    </if>
    order by ContentCode ASC

我正在尝试 运行 在 IDE 中查询,但不幸的是它不起作用。

谁能解释一下我做错了什么?

WHERE
   IncomingFlightId = 2568648 
   AND (IF 'MAIL' = 'MAIL'
   BEGIN
        SELECT 'and ContentCode = "M"'
   END ELSE BEGIN
        SELECT 'and ContentCode Not IN("M")'
   END)
   order by ContentCode ASC

不能直接在 SQL 语句中使用 IF,请改用 CASE WHEN test THEN returniftrue ELSE valueiffalse END(如果必须使用条件逻辑)

就是说,如果您这样做可能是可以避免的:

WHERE
  (somecolumn = 'MAIL' AND ContentCode = 'M') OR
  (somecolumn <> 'MAIL' and ContentCode <> 'M')

条件逻辑示例 SQL:

SELECT * FROM table
WHERE
  CASE WHEN col > 0 THEN 1 ELSE 0 END = 1

Case when runs a test and returns a value.您总是必须将 return 值与其他值进行比较。你不能做没有价值的事情。return。

虽然这里有点愚蠢,因为任何你可以在 case when 的真相中表达的东西,都可以直接在 where 子句的真相中更简单和可读地表达..

SELECT * FROM table
WHERE
  CASE WHEN type = 'x'
    THEN (SELECT count(*) FROM x) 
    ELSE (SELECT count(*) FROM y) 
  END = 1

SELECT * FROM table
WHERE
  (type = 'x' AND (SELECT count(*) FROM x) = 1) OR
   type <> 'x' AND (SELECT count(*) FROM y) = 1)  

虽然它对这样的事情很有用:

SELECT 
  bustourname, 
  SUM(CASE WHEN age > 60 THEN 1 ELSE 0 END) as count_of_old_people
FROM table 
GROUP BY bustourname

如果您希望编写一个有条件地构建 SQL 的存储过程,那么当然,您可以做到...

DECLARE @sql VARCAHR(max) = 'SELECT * FROM TABLE WHERE';
IF blah SET @sql = CONCAT(@sql, 'somecolumn = 1')
IF otherblah SET @sql = CONCAT(@sql, 'othercolumn = 1')
EXEC @sql...

但这仅在存储过程或类似过程的 sql 脚本中,它构建一个看起来像 SQL 的字符串,然后动态执行它。您不能在普通 SELECT 语句

中使用 IF

您正在 运行查询(此外它在语法上不正确 SQL)与 mybatis 生成和使用的查询无关。

你需要了解if in mybatis mapper 是如何工作的。 if 元素在 SQL 查询文本的生成阶段执行查询之前进行评估。如果 test 的值为真,则 if 元素的内容将包含在结果查询中。在您的情况下,根据传递给 mybatis 映射器方法的 screenFunction 参数,生成三个条件之一。

如果 screenFunction 的值为 MAIL 那么:

WHERE
IncomingFlightId=#{flightId}
    and ContentCode = 'M'
order by ContentCode ASC

如果 screenFunction 的值为 CARGO 那么:

WHERE
IncomingFlightId=#{flightId}
    and ContentCode Not IN('M')
order by ContentCode ASC

否则(如果 screenFunction 的值不是 MAIL 也不是 CARGO):

WHERE
IncomingFlightId=#{flightId}
order by ContentCode ASC

只有在生成查询文本后,才会通过 JDBC 对数据库执行。

因此,如果您想 运行 手动查询,您需要尝试其中一种查询。

您可能想做的一件事是将 enable logging 的 SQL 个查询和参数传递给它们,这样您就可以更轻松地重新 运行 它们。