构造准备好的语句时如何处理可选列

Posted

技术标签:

【中文标题】构造准备好的语句时如何处理可选列【英文标题】:How do I deal with optional columns when constructing a prepared statement 【发布时间】:2016-07-17 07:34:52 【问题描述】:

我想利用准备好的语句来插入/更新 postgres 数据库。 问题是该表包含可以为空的列,我在运行时可能有也可能没有值。 如果我没有任何要插入/更新的内容,我需要保留旧值。 有没有我可以用于这种情况的语法? 在这种情况下,最好的做法是什么,这似乎是一个非常普遍的问题?

附言 我使用带有普通 jdbc 的 java/scala。

【问题讨论】:

【参考方案1】:

当然,您可以只构造一个不包含您不想更新的列的语句。

如果这不是您的用例中的一个选项,您可以构造一个带有“标志”的 case 表达式来指示是否应该绑定列。

例如:

String sql = "UPDATE mytable " +
             "SET " +
             "col1 = CASE(? WHEN 1 THEN ? ELSE col1 END), " +
             "col2 = CASE(? WHEN 1 THEN ? ELSE col2 END) " +
             "WHERE id = ?";

PreparedStatement ps = con.prepareStatement(sql);

// col1 should be updated
ps.setInt(1, 1);
ps.setString(2, newValueCol1);

// col2 should not be updated
ps.setInt(3, 0);
ps.setString(4, null); // or any other value...

// bind the where clause
ps.setInt(5, someId);

ps.executeUpdate();

// close resources and clean up, omitted for brevity's sake

【讨论】:

谢谢。标志选项看起来正是我所需要的。它也适用于插入语句吗? 我的意思是在没有提供值时插入一个默认值。 @EliGolin 你可以在values 语句的values 子句中使用case 表达式。 适用于 SQL 案例使用,但在这种情况下,NamedParameterStatement 会比另一种情况更好。在您的示例中,它容易出错 @davidhxxx true,但请注意,这不是一个普通的 JDBC 类。它可能不是 OP 的有效解决方案。

以上是关于构造准备好的语句时如何处理可选列的主要内容,如果未能解决你的问题,请参考以下文章

想要启用可空引用类型时如何处理可选参数?

Go中的make函数如何处理可选参数? [复制]

如何处理可呈现图像的布局?

Spring Boot 如何处理可抛出对象

如何为java准备好的语句插入使用表名变量[重复]

spring 将可选查询参数映射到 sql 准备语句