在 SQL 查询中测试 null

Testing for null inside SQL query

我想为此实现搜索过滤器 table:

CREATE TABLE ACCOUNT(
 ID INTEGER NOT NULL,
 USER_NAME TEXT,
 PASSWD TEXT,
 FIRST_NAME TEXT,
 LAST_NAME TEXT,
 LAST_LOGIN DATE,
 DATE_REGISTERED DATE,
 ROLE INTEGER,
 CAN_LOGIN INTEGER
)
;

-- ADD KEYS FOR TABLE ACCOUNT

ALTER TABLE ACCOUNT ADD CONSTRAINT KEY1 PRIMARY KEY (ID)
;


SELECT * FROM ACCOUNT 
WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)
ORDER BY %S %S offset ? limit ?;

但是,当我的搜索过滤器为空时,出现此错误:

org.postgresql.util.PSQLException: ERROR: invalid input syntax for integer: "null" Position: 30

如何编辑 SQL 查询,使其在 searchString 为空时跳过 WHERE 子句?

这里是 Java 方法:

public List<AccountsObj> list(int firstRow, int rowCount, String sortField, boolean sortAscending) throws SQLException
    {
        String SqlStatement = null;

        if (ds == null)
        {
            throw new SQLException();
        }

        Connection conn = ds.getConnection();
        if (conn == null)
        {
            throw new SQLException();
        }

        String sortDirection = sortAscending ? "ASC" : "DESC";

        SqlStatement = "SELECT * FROM ACCOUNT "
            + " WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)"
            + " ORDER BY %S %S offset ? limit ? ";

        String sql = String.format(SqlStatement, sortField, sortDirection);

        PreparedStatement ps = null;
        ResultSet resultSet = null;
        List<AccountsObj> resultList = new ArrayList<>();

        try
        {
            conn.setAutoCommit(false);
            boolean committed = false;

            ps = conn.prepareStatement(sql);
            ps.setInt(1, firstRow);
            ps.setInt(2, rowCount);

            resultSet = ps.executeQuery();
            resultList = ProcessorArrayList(resultSet);

            conn.commit();
            committed = true;

        }
        finally
        {
            ps.close();
            conn.close();
        }

        return resultList;
    }

您可以替换 java 代码的这一行:

+ (searchString == null || searchString.length == 0 ) ? "" : (" WHERE '" + searchString + "' IN (ID, USER_NAME, FIRST_NAME, LAST_NAME)")

它主要检查 searchString 是否为空,只有在不为空时才添加该行

使用 SQL 检查 null 搜索字符串,您可以执行以下操作:

SELECT * FROM account WHERE ? IS NULL OR ? IN (user_name, first_name, last_name)

此处如果参数为NULL,则? IS NULL会短路,第二部分不会被计算

请注意,我在这里使用了两个具有相同值(您的搜索字符串)的参数绑定,并且 ID 列消失了 - 您不能混合使用 varcharintegerIN 子句中。

编辑 对于通配符搜索,您可以使用 LIKEILIKE(对于不区分大小写的搜索)

SELECT * FROM account WHERE 
     (trim(?) = '') IS NOT FALSE 
    OR user_name like ? 
    OR first_name like ? 
    OR last_name like ?

使用准备好的语句,你可以这样调用它(注意你必须绑定相同的参数四次)

try (PreparedStatement ps = conn.prepareStatement(sql)) {

    ps.setString(1, searchString);
    ps.setString(2, searchString);
    ps.setString(3, searchString);
    ps.setString(4, searchString );

    try (ResultSet rs = ps.executeQuery()) {
        // read data 
    }
}