在PreparedStatement中绑定null变量

时间:2010-04-16 01:14:16

标签: java jdbc null

我发誓这曾经工作过,但在这种情况下不是这样。我正在尝试匹配col1,col2和col3,即使其中一个或多个为null。我知道在某些语言中我不得不诉诸((? is null AND col1 is null) OR col1 = ?)这样的迂回曲折。这需要吗?

        PreparedStatement selStmt = getConn().prepareStatement(
                "SELECT     * " +
                "FROM       tbl1 " +
                "WHERE      col1 = ? AND col2 = ? and col3 = ?");
        try
        {
            int col = 1;
            setInt(selStmt, col++, col1);
            setInt(selStmt, col++, col2);
            setInt(selStmt, col++, col3);
            ResultSet rs = selStmt.executeQuery();
            try
            {
                while (rs.next())
                {
                   // process row
                }
            }
            finally
            {
                rs.close();
            }
        }
        finally
        {
            selStmt.close();
        }

   // Does the equivalient of stmt.setInt(col, i) but preserves nullness.
    protected  static void setInt(PreparedStatement stmt, int col, Integer i)
    throws SQLException
    {
        if (i == null)
            stmt.setNull(col, java.sql.Types.INTEGER);
        else
            stmt.setInt(col, i);
    }

4 个答案:

答案 0 :(得分:9)

这可能取决于JDBC驱动程序,但在大多数情况下,是的,您需要使用上面显示的更多扩展形式。

JDBC预处理语句通常是围绕参数化查询的本机实现的相对较薄的包装器,即查询带有?代替参数传递给查询编译器并进行编译,因此,稍后,当您调用stmt.executeQuery()时,语句无法从column = ?调整为column IS NULL。这不仅仅是JDBC the semantics of NULL in SQL的限制。对于SQL,x = NULL未定义为x <> NULL

也就是说,一些JDBC驱动程序可能违反SQL中NULL - ity的概念,并允许setNull()将语句从= ?转换为IS NULL这将是非常高的标准行为(虽然可以通过编写某种查询预处理方法轻松完成)。

答案 1 :(得分:3)

您使用的数据库是什么?

但至少在Oracle中,等式(和不等式)永远不会匹配NULL,你必须编写IS NOT NULL。

答案 2 :(得分:1)

通常,等于NULL的东西总是假的(即使是NULL,因此SELECT * FROM tbl WHERE NULL=NULL;将是一个空集),所以如果你想接受像这样的空等式,你可能需要做很长的事情。 / p>

答案 3 :(得分:0)

我知道这可能为时已晚,但仅仅是因为它对我而言似乎是Oracle的黑客攻击:

SQL:

SELECT.....FROM....WHERE NVL(CUST_ID,0)=? AND NVL(vendor_id,0)=?

在您执行jdbc调用的代码中,调用类似这样的代码:

pstmt.setString(1, ( xxo.getCustId().equals("")) ? "0":xxo.getCustId());
pstmt.setString(2, ( xxo.getVendId().equals("")) ? "0":xxo.getVendId());
rs = pstmt.executeQuery();