如何在 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 值?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 cpp 文件中为多种类型创建模板类成员实现

如何实现 SAFEARRAY(long) 参数?

oracle 如何把long类型转换成字符类型

如何在 Laravel Eloquent 查询(或使用查询生成器)中为表起别名?

如何在 Swift 中为 Image 实现 Hashable 结构

如何在 asp.net core 3.1 中为每种类型的请求启用 Cors