代码之家  ›  专栏  ›  技术社区  ›  beldaz Nicolas W.

Matlab数据库准备的语句和绑定变量

  •  4
  • beldaz Nicolas W.  · 技术社区  · 9 年前

    我对Matlab相当陌生,但我已经成功地使用它与数据库(在我的例子中是PostgreSQL)交互,方法是遵循有关如何 connect to a database using JDBC drivers ,然后 executing a query with exec 然而,在后一种情况下给出的示例涉及将数据粘贴到查询中,这可能是低效的,并且对SQL注入开放。

    我真正想做的是使用绑定变量,例如在 JDBC PreparedStatement 。我在文档中找不到关于此的任何信息。有办法做到这一点吗?

    2 回复  |  直到 9 年前
        1
  •  6
  •   Peter Gagarinov    7 年前

    是的,正如您所指出的,这是可能的,但您也可以通过Matlab数据库工具箱来完成所有这一切。

    通过Matlab数据库工具箱插入数据

    事实上,这个工具箱通过直接JDBC连接与PostgreSQL一起工作。此外, datainsert fastinsert ,通过专门创建的准备语句进行工作。这两者之间的唯一区别在于各自准备的语句中填充数据的方式。 快速插入件 在Matlab中使用与您提到的完全相同的技术(使用不同的setter,如 setDouble , setBoolean , setTimestamp 等等 当然 setObject ). 但事实证明,在大数据量的情况下,这种方法很难使用,因为在这种情况下 快速插入件 变得非常缓慢。 数据插入 通过Java中的某个对象在创建的准备语句中填充数据 com.mathworks.toolbox.database.writeTheData 班这个类实现了两个方法 doubleWrite cellWrite . 双重写入 允许用数字标量数据填充准备好的语句。 单元格写入 假设数据以单元格矩阵的形式传递,每个单元格中有一个标量对象(对象可以是数字、逻辑Matlab标量、Matlab字符串或JDBC驱动程序支持的标量Java对象,例如, org.postgresql.jdbc.PgArray 在数组的情况下) 对应的字段和元组。因此 set对象 来自Matlab(这可能导致 显著的开销)作为第一步,用必要的对象填充所提到的单元矩阵更有效 然后打电话 数据插入 作为第二步,从Matlab数据库工具箱中删除。

    数据插入方法的性能

    但在这种情况下,插入的所有对象都有Matlab类型 (标量、字符串、矩阵、多维数组、结构和任意其他Matlab类型), 至少有一种更有效的方法可以使用特殊的高性能PostgreSQL插入数据 客户端库100%用C语言编写,并基于libpq。它被称为 PgMex . 它对于大数据量(约1Gb及以上)或 需要插入非标量数据(数组)。在这种情况下 快速插入件 数据插入 演示了由于JDBC驱动程序对大型数据集的限制而导致的性能下降和Java堆内存持续不足。这很容易 从以下图片中可以看出:

    The case of scalar numeric data The case of arrays

    在这里 快速插入件 数据插入 batchParamExec 来自PgMex(参见 https://pgmex.alliedtesting.com/#batchparamexec 详细信息)。第一张图片用于标量数字数据,第二张图片用于数组。每个图形的端点对应 通过相应的方法传递到数据库中的某个最大数据量没有任何错误。 数据量大于最大值(特定于每个方法)会导致Java堆内存不足问题 (每个实验的Java堆大小在每个图的顶部指定)。 有关实验的详细信息,请参见以下内容 paper with full benchmarking results for data insertion .

    编辑:现在 PgMex 支持免费学术许可。

        2
  •  5
  •   beldaz Nicolas W.    9 年前

    看起来我已经回答了自己的问题,所以我分享了我的爱。AFAICS数据库工具箱非常基本,但幸运的是,可以直接使用Java的JDBC API,正如我在支持团队对 this question .

    因此,准备好的语句可以像这样使用绑定变量:

    % Assume schema
    % CREATE TABLE (idcol SERIAL PRIMARY KEY, colX INTEGER, colY INTEGER);
    
        jdbcconn = conn.Handle
            stmt = jdbcconn.prepareStatement(['INSERT INTO mytable ('...
                'colX, colY) '...
                'VALUES (?,?) '...
                'RETURNING idcol']);
        stmt.setObject(1, x);    
        stmt.setObject(2, y);    
        rs = stmt.executeQuery();
        success = rs.next();
        newentry_id = getInt(1);
        close(rs);
        close(stmt);