代码之家  ›  专栏  ›  技术社区  ›  Paul Tomblin

在PreparedStatement中绑定空变量

  •  12
  • Paul Tomblin  · 技术社区  · 14 年前

    我发誓这以前管用,但现在不行。我尝试匹配col1、col2和col3,即使其中一个或多个为空。我知道在某些语言中,我不得不使用诸如 ((? 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 回复  |  直到 9 年前
        1
  •  9
  •   ig0774    14 年前

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

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

    也就是说,一些JDBC驱动程序可能违反 NULL -并允许setnull()将语句从 = ? IS NULL 这将是非常不标准的行为(尽管通过编写某种查询预处理方法可以很容易地完成)。

        2
  •  3
  •   Thilo    14 年前

    您使用的是什么数据库?

    但至少在Oracle中,相等(和不相等)从不匹配空值,必须编写不为空值。

        3
  •  1
  •   Michael Mrozek    14 年前

    一般来说,等于空的东西总是假的(即使是空的,所以 SELECT * FROM tbl WHERE NULL=NULL; 将是一个空集),因此如果您希望接受这样的空相等,那么可能需要做很长的一段时间。

        4
  •  0
  •   hephestos    9 年前

    我知道这可能太晚了,但仅仅是为了它,甲骨文的黑客似乎在我工作:

    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();