如何在 SqlData 实现中为 Long 类型的属性传递 NULL 值?
Posted
技术标签:
【中文标题】如何在 SqlData 实现中为 Long 类型的属性传递 NULL 值?【英文标题】:How can I pass NULL value in SqlData implementation for Long typed attribute? 【发布时间】:2014-04-02 13:28:49 【问题描述】:我有大量原始数据(SqlData 对象类型)进入并尝试使用创建的用户定义类型插入 Oracle。
问题仅针对具有一些为空的 Long 属性的记录。 我得到这些记录的 NullPointer 异常 - 因为它试图在空对象上调用 toString。
有没有办法为 Long 列(在 SQLOutput 流中)写入空值?
我知道这可以通过更改为 String 类型来实现,但我无法触及 PL/SQL 函数,因为它在很多地方都使用过。
public classMyClass extends MyBaseType implements SQLData
public void writeSQL(SQLOutput stream) throws SQLException
stream.writeString(getSource());
stream.writeTimestamp(getDtm());
stream.writeString(getUniqueId());
stream.writeString(getType());
stream.writeLong(getResponseCode());
当 getResponseCode() 为 null 时,最后一行会导致 NullPointer 异常。
知道如何在不改变类型(为字符串)的情况下处理这个问题吗?
最后尝试的选项是,
private void writeNullPossibleNumber(SQLOutput stream, Integer intValue) throws SQLException
if (intValue==null)
stream.writeBigDecimal(null);
else
stream.writeInt(intValue);
上述解决方案工作正常。
参考: http://docs.oracle.com/cd/A87860_01/doc/java.817/a81357/sampcod3.htm
感谢大家的帮助
【问题讨论】:
【参考方案1】:如您所见 SQLOutput.writeLong
等待 primitive
long
,但您似乎尝试提供包装器 Long
。在这种情况下,null
当然不能转换为任何primitive
。
所以,或者只是在writeLong
之前添加null check
,或者更改整个逻辑,如果您根本无法将空值写入数据库。
【讨论】:
你是对的! - 它期望原始类型。我认为我只能适应这一点,但问题是它用于设置 NULL 值的早期实现(使用 PreparedStatement setLong 调用)。有些是 id 值,我不能在那些地方假设 0。 很高兴知道。所以,添加我的声誉;-) 谢谢!如果空检查指示空值,您可以通过指示做什么来改进答案。幸运的是,OP 用最终解决方案更新了他的问题。【参考方案2】:由于自动拆箱,您会得到 NPE
。你应该明确写空值,试试这样:
if (getResponseCode() != null) stream.writeBigDecimal(new BigDecimal(getResponseCode()));
else stream.writeBigDecimal(null);
【讨论】:
我得到以下 - 错误代码 [17059];无法转换为内部表示:;嵌套异常是 java.sql.SQLException: 无法转换为内部表示: 好的。试试这个stream.writeBigDecimal(null)
。由于任何数字都以 NUMBER 的形式填充到数据库中(尤其是对于 Oracle),这将是null
数字的一种解决方法。
@ArtemBilan 我修改了答案。我实际上并没有使用SQLOutput
,而是在 javadoc 中查找了发送 null 的方法。
你不能混合两种类型——if(true) 相同类型,否则相同类型。我试过了。但引起:java.sql.SQLException:无法转换为内部表示:在 oracle.jdbc.oracore.OracleTypeNUMBER.toNUMBER(OracleTypeNUMBER.java:268)
@RajeshBalan 尝试仅使用BigDecimal
。我更新了我的答案。【参考方案3】:
您可以选择以下任一选项:
明确使用 NULL 作为空值(使用 if 语句选择 NULL 或 toString) 如果值为 null,则从插入中删除该列类似下面的帮助类可能对你有用。
public class DatabaseHelper
private static final String CNULL = "NULL";
static public String fixValue(Object value)
if (value == null)
return CNULL;
else
return value.toString();
【讨论】:
这里的问题是我需要接触服务器合同来支持这一点。就像我说的,早期的实现是使用 PreparedStatement setLong 调用,其中也允许使用 null。有些值是 ID,这些是 null 我不能假设它是 0,因为在我之前的实现中它被设置为 NULL以上是关于如何在 SqlData 实现中为 Long 类型的属性传递 NULL 值?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Laravel Eloquent 查询(或使用查询生成器)中为表起别名?