SQL WHERE 中的多个条件 AND

Multiple conditional ANDs in SQL WHERE

我目前正在 Java 中使用一个字符串 运行 一个 SQL 语句

String fruitName = "apple";
String colorOfFruit = a < b ? null : "red";
String sizeOfFruit = c > d ? null : "big";

String sql = "SELECT * FROM my_table WHERE fruit = ? " +
 if (colorOfFruit != null) sql += "AND color = ? ";
 if (sizeOfFruit != null) sql += "AND size = ? "
 sql += "ORDER BY fruit";


int i = 1;
PreparedStatement stmt = databaseConnection.prepareStatement(sql)
stmt.setString(i++, fruitName);
if (colorOfFruit != null) stmt.setString(i++, colorOfFruit);
if (sizeOfFruit != null) stmt.setString(i++, sizeOfFruit);

ResultSet rs = stmt.executeQuery();

有什么方法可以将其转换为 SQL 查询,我可以 运行 使用 Java 中的 CallableStatement?我正在考虑创建一个存储过程,但我不确定如何有条件地使用 AND 语句。

CREATE PROCEDURE MyProcedure
    @fruitName NVARCHAR(50),
    @colorOfFruit NVARCHAR(50),
    @sizeOfFruit NVARCHAR(50)
AS
BEGIN
    SELECT * FROM my_table WHERE fruit = @fruitName
    -- add an and statement here if @colorOfFruit is not null
    -- add another and statement here if @priceOfFruit is not null
    ORDER BY fruit
END

只需使用 AND/OR 逻辑,例如

IF 参数为 null OR 参数 = 列值 例如

SELECT *
FROM my_table
WHERE fruit = @fruitName
-- add an and statement here if @colorOfFruit is not null
and (@colorOfFruit is null or color = @colorOfFruit)
-- add another and statement here if @sizeOfFruit is not null
and (@sizeOfFruit is null or Size = @sizeOfFruit)
ORDER BY fruit

您当前的解决方案是最好的,因为它允许 SQL 优化器选择最佳访问计划。

不过,我会使用三元条件运算符来实现,并记得使用 try-with-resources:

String sql = "SELECT *" +
              " FROM my_table" +
             " WHERE fruit = ?" +
           (colorOfFruit == null ? "" :
               " AND color = ?") +
           (sizeOfFruit == null ? "" :
               " AND size = ?") +
             " ORDER BY fruit";
try (PreparedStatement stmt = databaseConnection.prepareStatement(sql)) {
    int paramIdx = 0;
    stmt.setString(++paramIdx, fruitName);
    if (colorOfFruit != null)
        stmt.setString(++paramIdx, colorOfFruit);
    if (sizeOfFruit != null)
        stmt.setString(++paramIdx, sizeOfFruit);
    try (ResultSet rs = stmt.executeQuery()) {
        while (rs.next()) {
            // code here
        }
    }
}