在PreparedStatement中绑定空变量

发布于 2024-08-29 02:08:11 字数 1217 浏览 2 评论 0原文

我发誓这曾经有效,但在这种情况下不起作用。我试图匹配 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);
    }

I swear this used to work, but it's not in this case. I'm trying to match col1, col2 and col3, even if one or more of them is null. I know that in some languages I've had to resort to circumlocutions like ((? is null AND col1 is null) OR col1 = ?). Is that required here?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南七夏 2024-09-05 02:08:12

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

JDBC 准备好的语句通常是围绕参数化查询的本机实现的相对较薄的包装器,即带有 ? 的查询。 in place of 参数传递给查询编译器并编译,因此,稍后,当您调用 stmt.executeQuery() 时,该语句无法从 column = ? 调整为 column IS NULL。这与其说是 JDBC 的限制,不如说是 SQL 中 NULL 的语义 。对于 SQL,x = NULL 未定义,x <> 也是如此。空。

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

This may depend on the JDBC driver, but for the most part, yes, you would need to use the more extended form you show above.

JDBC prepared statements are usually relatively thin wrappers around a native implementation of a parameterized query, i.e., the query with ? in place of parameters are passed to the query compiler and compiled, so, later, when you call stmt.executeQuery(), the statement cannot be adjust from a column = ? to column IS NULL. This isn't so much a limitation of JDBC as it the semantics of NULL in SQL. For SQL x = NULL is undefined as is x <> NULL.

That said, some JDBC drivers may violate the notion of NULL-ity in SQL and allow setNull() to transform the statement from = ? to IS NULL this would be highly non-standard behavior (though it could be easily accomplished by writing some sort of query pre-processing method).

对你而言 2024-09-05 02:08:12

你使用什么数据库?

但至少对于 Oracle,相等(和不等)永远不会匹配 NULL,你必须写 IS NOT NULL。

What database are you using?

But at least with Oracle, equality (and inequality) never matches NULL, you have to write IS NOT NULL.

那一片橙海, 2024-09-05 02:08:12

一般来说,等于 NULL 的东西总是假的(甚至是 NULL,所以 SELECT * FROM tbl WHERE NULL=NULL; 将是一个空集),所以如果你想要接受这样的空相等

Generally something being equal to NULL is always false (even NULL, so SELECT * FROM tbl WHERE NULL=NULL; will be an empty set), so you probably do need to do it the long way if you want to accept null equality like that

云柯 2024-09-05 02:08:12

我知道这也许为时已晚,但只是为了它,对 Oracle 的一个 hack 在我看来有效:

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

I know that is too late perhaps, but just for the sake of it a hack for Oracle which seems to me working:

SQL:

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

And in the code where you do the jdbc call something like this:

pstmt.setString(1, ( xxo.getCustId().equals("")) ? "0":xxo.getCustId());
pstmt.setString(2, ( xxo.getVendId().equals("")) ? "0":xxo.getVendId());
rs = pstmt.executeQuery();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文