如何在 Oracle 的 SQLData.writeSQL() 中将 java.sql.Array 写入 java.sql.SQLOutput

2023-11-24

我已经实施了java.sql.SQLData为了使用 ojdbc6 将 UDT 对象绑定到准备好的语句。现在,我的一些 UDT 包含数组。我现在需要做的是:

class MyType implements SQLData {
  public void writeSQL(SQLOutput stream) throws SQLException {
    Array array = //...
    stream.writeArray(array);
  }
}

为了构造 Oracle 数组,我需要一个 JDBC 连接。通常,这是这样完成的:

OracleConnection conn = // ...
Array array = conn.createARRAY("MY_ARRAY_TYPE", new Integer[] { 1, 2, 3 });

然而,在那writeSQL(SQLOutput)方法,我没有连接。另外,由于难以用简洁的问题解释的原因,我无法在MyType。我能以某种方式从中提取这种联系吗SQLOutput?我想避免使用这样的不稳定结构:

// In ojdbc6, I have observed a private "conn" member in OracleSQLOutput:
Field field = stream.getClass().getDeclaredField("conn");
field.setAccessible(true);
OracleConnection conn = (OracleConnection) field.get(stream);

有任何想法吗?备择方案?


这是我为解决此问题所做的操作。它不漂亮,但很有效。

我在我的类中添加了一个方法来实现SQLData接收一个java.sql.Connection并设置相应的java.sql.ARRAY对象。

像这样的东西:

public class MyObject01 implements SQLData {
   private String value;
   private MyObject02[] details; // do note that details is a java array
   // ... also added getters and setters for these two properties

   private Array detailsArray;

   public void setupArrays(oracle.jdbc.OracleConnection oconn)
      throws SQLException
   {
       detailsArrays = oconn.createARRAY(MyObject02.ORACLE_OBJECT_ARRAY_NAME, getDetails());
       // MyObject02.ORACLE_OBJECT_ARRAY_NAME must be the name of the oracle "table of" type name
       // Also note that in Oracle you can't use JDBC's default createArray
       // since it's not supported. That's why you need to get a OracleConnection
       // instance here. 
   }       

   @Override
   public void writeSQL(Stream stream) throws SQLException {
       stream.writeString(getValue());
       stream.writeArray(detailsArray); // that's it
   }

   @Override
   public void readSQL(Stream stream) throws SQLException {
       setValue(stream.readString());
       Array array = stream.readArray();
       if (array != null) {
           setDetails((MyObject02[])array.getArray());
       }
   }

这是第一部分。

然后,在过程调用中使用该对象之前,调用setupArrays该对象上的方法。例子:

public class DB {
    public static String executeProc(Connection conn, MyObject01 obj)
        throws SQLException
    {
        CalllableStatement cs = conn.prepareCall(" { ? = call sch.proc(?) }");
        cs.registerOutParameter(1, Types.VARCHAR);
        obj.setupArrays((oracle.jdbc.Connection)conn);
        cs.setObject(2, obj, Types.STRUCT);
        cs.executeUpdate();
        String ret = cs.getString(1);
        cs.close();
        return ret;
    }
}

当然,在连接时,您需要正确注册您的类型:

Connection conn = DriverManager.getConnection("jdbc:oracle://localhost:1521/XE", "scott", "tiger" );
conn.getTypeMap().put(MyObject01.ORACLE_OBJECT_NAME, MyObject01.class);
conn.getTypeMap().put(MyObject02.ORACLE_OBJECT_NAME, MyObject02.class);
conn.getTypeMap().put(MyObject02.ORACLE_OBJECT_ARRAY_NAME, MyObject02[].class);

希望能帮助到你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Oracle 的 SQLData.writeSQL() 中将 java.sql.Array 写入 java.sql.SQLOutput 的相关文章

随机推荐

  • 使用 ClosedXML 将 Gridview 导出到 Excel,而不发出警告:您尝试打开的文件格式不同

    我正在开发 ASP NET 4 5 Webform 并且有一个 Gridview 具有自定义 TemplateField 并从 sqlDataSource 获取数据 我有这个事件将 gridview 内容导出到 Excel 工作表 它的工作
  • 如何从 C# 中的一组图像创建 H.264 编码的电影?

    我今天做了很多搜索 C 库 这将允许我创建 H 264 编码的视频文件 有谁知道是否存在这样的库或第三方组件 Use ffmpeg 我建议直接运行 ffmpeg 进程 如本示例所示 http jasonjano wordpress com
  • 递归释放 C 结构体

    我有一个结构 仅包含指向我分配的内存的指针 有没有一种方法可以递归地释放每个作为指针的元素 而不是对每个元素调用 free 例如 假设我有这样的布局 typedef struct vertex typedef struct normal t
  • 如何将 SQL 数据库嵌入/附加到 Visual C# 中?

    这是我第一次使用 SQL 这可能是一个愚蠢的问题 但我做了一些研究 但我认为我没有找到我想要的东西 我想要的是一种创建将在我的 C 程序中使用的私有 SQL 数据库的方法 我已经在 SQL Server Express 中创建了一个数据库
  • C++中虚表的结构是怎样的?

    例如 我有两个 接口 和类类型 class IPlugin public virtual void Load void 0 virtual void Free void 0 class IFoo public virtual void Fo
  • 在哪里下载 your_client_secret_File.json 文件

    我正在使用 YouTube API 但首先 我需要凭证文件 your client secret File json 通过遵循本教程https developers google com youtube analytics referenc
  • Clang 中 __int128_t 的错误?

    这段小代码可以使用 GCC 和 Clang 进行编译 但会给出不同的结果 include
  • Python Twisted 中的内存泄漏:它在哪里?

    我有一个负载下的 Twisted 服务器 当服务器处于负载状态时 内存使用量会增加 并且永远不会被回收 即使没有更多的客户端 下次进入高负载时 内存使用量会再次增加 这是当时情况的快照 RSS 内存为 400 MB 通常最大客户端数应为 2
  • HTML5 验证中的空标题警告

    我尝试验证我的 HTML 代码 但发现了此警告 空标题 See here 显然标题不为空 的内容 h3 h3 在 WordPress 中由以下方式生成the title 功能 所以 我不明白为什么会发生这种情况 有人可以解释一下问题是什么吗
  • 使用接口进行 IList 和 List 转换

    我大致了解接口 继承和多态性 但有一件事让我感到困惑 在这个例子中 Cat实施IAnimal而且当然List实施IList IList
  • 如何在 html 游戏中保存进度

    我想知道如何保存玩家在我正在制作的游戏中取得的进度 我可以通过 cookies 来做到这一点吗 或者我还可以如何将其保存到玩家的计算机上 感谢您的所有帮助 使用 Javascript 在本地保存几乎有两种选择 它们是cookies and
  • 将 Eigen 库添加到 Android NDK

    我需要在我的 Android Studio 项目中包含 Eigen 库来执行一些线性代数运算并使用我为桌面开发的一些 C 代码 我一直在寻找有关此主题的信息 但没有太多 而且我是 Android NDK 的新手 Eigen 库不需要编译 所
  • 正则表达式匹配除字符列表之外的所有内容

    我想匹配包含除指定字符之外的所有内容的行 I V X M C D L new Regex is I V X M C D L 应该匹配除中提到的字符之外的所有内容OR list 应匹配 name is a 不应该匹配 edition is I
  • Python IMAP 搜索指定电子邮件地址或发送至指定电子邮件地址

    我将其与 Gmail 的 SMTP 服务器一起使用 并且我想通过 IMAP 搜索发送到某个地址或从某个地址接收的电子邮件 这就是我所拥有的 mail imaplib IMAP4 SSL imap gmail com mail login u
  • 命名约定 - C++ 和 C# 变量中的下划线

    常见的是看到一个 var类字段中的变量名 下划线是什么意思 所有这些特殊命名约定都有参考吗 下划线只是一种约定 而已 因此 每个人的使用总是有些不同 以下是我对这两种语言的理解 在C 中 下划线通常表示私有成员变量 在 C 中 我通常只在为
  • 使用绝对定位是否被认为是不好的做法? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我正在开发一个网页 在其中放置一个类似国际象棋的游戏的棋盘 以及几个棋子托盘 这一切都是使用 HTML 完成的 使用 jQuery 在玩游戏时进行动态更新 在某个地方 我认为在页面内使用元
  • p5.j​​s 中的碰撞处理

    我一直在使用 p5 js 并且已经弄清楚如何让对象来检测碰撞 但我对如何处理这些碰撞感到非常困惑 我尝试将玩家速度设置为 0 但随后玩家卡住了 我也尝试过将碰撞分开到每一侧 但这也不起作用 这是我的带有碰撞函数的玩家构造函数 class P
  • React CSS 模块的几个 CSS 文件

    我有2个相同的组件 它们的样式有点不同 所以我想重用通用样式 但不想为它们使用全局CSS 我该如何实现呢 import React from react import commonStylesfrom common table css im
  • 有没有在react-native中实现JavaScriptModule的指南?

    有兴趣直接实施native to javascript调用react native 但没有找到任何指南 请帮助提供一些在 React Native 中创建和注册本机 JavaScript 模块的示例 已经从官方那里找到了代码原生模块 and
  • 如何在 Oracle 的 SQLData.writeSQL() 中将 java.sql.Array 写入 java.sql.SQLOutput

    我已经实施了java sql SQLData为了使用 ojdbc6 将 UDT 对象绑定到准备好的语句 现在 我的一些 UDT 包含数组 我现在需要做的是 class MyType implements SQLData public voi