在SQL查询中测试null

时间:2016-04-09 18:26:31

标签: java sql postgresql postgresql-9.3

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

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

如果searchString为空,如何以跳过WHERE子句的方式编辑SQL查询?

这是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;
    }

2 个答案:

答案 0 :(得分:1)

使用SQL检查您可以执行的null搜索字符串:

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

如果参数为? IS NULL,则NULL将短路,而第二部分将不会被评估。

请注意,我在这里使用了两个具有相同值(您的搜索字符串)的参数绑定,且ID列已消失 - 您无法将varcharinteger混合在一起IN条款。

修改对于通配符搜索,您可以使用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 
    }
}

答案 1 :(得分:0)

您可以替换此java代码行:

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

它基本上检查searchString是否为空,并且仅当行不是

时才添加该行