【问题标题】:preparedStatement setting null for NUMBER_ARRAY doesnt workNUMBER_ARRAY 的preparedStatement 设置为空不起作用
【发布时间】:2015-03-27 20:57:23
【问题描述】:
ArrayDescriptor arrayDescriptor =
    ArrayDescriptor.createDescriptor("NUMBER_ARRAY", conn);

if (parameter != null) {
    ARRAY oracleArray =
            new ARRAY(arrayDescriptor, conn, intList.toArray());
    ps.setArray(i, oracleArray);
} 
else {
    ps.setNull(i, Types.ARRAY, "NUMBER_ARRAY");
}

在上面的代码中,我试图将 oracleArray 设置为 null。它不会抛出任何异常。但我猜甲骨文并不认为它是空的。传入空值的方法是什么,我的意思是将一个列表设置为空值,orcle DB 可以将其视为NUMBER_ARRAY(null),稍后将传递给存储过程(SP)。 SP 准备好获取一个空列表。如果它是一个空列表,它什么也不返回。如果它不是一个空列表,它将给出结果。这是一个有效的场景。

【问题讨论】:

  • 您希望数据库中的 Oracle 集合本身为空,还是作为一个元素的集合,其中该元素为空?
  • 基本上我希望 oracle 将我的参数作为 NUMBER_ARRAY(null)。
  • 我想将一个空列表从 java 传递到 oracle 存储过程,并且该 proc 应该将其作为 NUMBER_ARRAY(null).. 我已经通过传入 NUMBER_ARRAY(null) 运行存储过程并且可以工作美好的。但是当从 java 调用该 SP 时传入 null 列表不起作用。我知道我们可以将 int 设置为 null 作为 ps.setNull(i, int),但不确定我们如何为 java 中的 BigInteger 列表做些什么。对于您的问题,我希望 oracle 集合本身为空。 @rgettman
  • @Raj:你在自相矛盾。你说如果你通过你的存储过程NUMBER_ARRAY(null) 它工作正常,但你也说'你希望你的集合本身为空'。 NUMBER_ARRAY(null) 不是一个空集合,它是一个包含单个 NULL 值的 1 元素集合。请明确说明您想要什么。
  • @LukeWoodward:对不起我的发言。我没有意识到 NUMBER_ARRAY(null) 相当于包含单个 null 的集合的 1 个元素。我的问题是我想传入一个没有添加任何值的列表。所以我的理解是我需要传入一个 1 元素为 null 的列表才能使这个场景生效。

标签: java oracle stored-procedures prepared-statement


【解决方案1】:

您似乎对空数组、空数组和仅包含单个NULL 值的数组有些困惑。

NULL 数组不存在数组,就像 NULL 数字不存在数字一样。空数组是存在的数组,但其中包含 0 个元素。两者都不同于NUMBER_ARRAY(null),后者是一个包含单个NULL 值的数组。

数组上的COUNT 方法返回数组中元素的数量,说明了这三者之间的区别。

首先,一个NULL 数组:

SQL> declare
  2    l_null_array     number_array  := null;
  3  begin
  4    dbms_output.put_line('Count: ' || l_null_array.COUNT);
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06531: Reference to uninitialized collection
ORA-06512: at line 4

在这里,我们得到一个错误。我们无法找出l_null_array 中有多少元素,因为我们没有一个数组来查找其中的元素数量。

其次,空数组:

SQL> declare
  2    l_empty_array    number_array  := number_array();
  3  begin
  4    dbms_output.put_line('Count: ' || l_empty_array.COUNT);
  5  end;
  6  /

Count: 0

PL/SQL procedure successfully completed.

在这里,我们可以找到一个空数组中的元素个数,这个数为零。

最后是一个只包含NULL的数组:

SQL> declare
  2    l_array_containing_null    number_array  := number_array(null);
  3  begin
  4    dbms_output.put_line('Count: ' || l_array_containing_null.COUNT);
  5  end;
  6  /
Count: 1

PL/SQL procedure successfully completed.

这个数组中有一个元素,那个元素是NULL

请注意,您可以将任意数量的参数传递给NUMBER_ARRAY 构造函数,这些值将是数组的初始内容。例如,NUMBER_ARRAY(1, 4, 18, 11, 22, 6) 创建一个包含 6 个元素的数字数组。

那么,我们如何使用 JDBC 设置各种数组呢?

  • 要设置NULL 数组,请使用

    ps.setNull(i, Types.ARRAY, "NUMBER_ARRAY");
    

    正如你在上面所做的那样。

  • 对于空数组,使用:

    ps.setArray(i, new ARRAY(arrayDescriptor, conn, new Integer[0]));
    
  • 对于仅包含单个 NULL 值的数组,请使用

    ps.setArray(i, new ARRAY(arrayDescriptor, conn, new Integer[] { null }));
    

我在这些示例中使用Integer 数组,但其他数字类型也应该可以。

【讨论】:

  • 感谢您的回答。抱歉,我无法向您解释我的问题。我正在使用列表中从未初始化的场景。所以我的场景是指你的第一个。无论如何,我需要将所有这些选项交给 DB 家伙,并弄清楚他喜欢哪种方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
  • 2021-07-19
  • 1970-01-01
  • 2012-07-14
  • 2014-07-14
  • 1970-01-01
相关资源
最近更新 更多