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

Matlab database prepared statements and bind variables

我是 Matlab 的新手,但我已经成功地使用它与数据库交互(在我的例子中是 PostgreSQL),方法是遵循关于如何 connect to a database using JDBC drivers, and then executing a query with exec 的官方文档.但是,后一种情况给出的示例涉及将数据粘贴到查询中,这可能效率低下并且容易受到 SQL 注入。

我真正想做的是使用绑定变量,就像在 JDBC PreparedStatement 中所做的那样。我在文档中找不到任何关于此的内容。有什么办法可以做到这一点吗?

看来我已经成功回答了我自己的问题,所以我要分享这份爱。 AFAICS 数据库工具箱非常基础,但幸运的是可以直接使用 Java 的 JDBC API,正如我在支持团队对 this question.[=12 的回复中发现的那样=]

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

% 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);

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

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

事实上,此工具箱通过直接 JDBC 连接与 PostgreSQL 配合使用。此外,datainsertfastinsert 两种实现的数据插入方法都通过专门创建的准备语句工作。这两者之间的唯一区别在于各自准备好的语句填充数据的方式。 fastinsert 在 Matlab 中通过使用与您提到的完全相同的技术(通过使用 setDoublesetBooleansetTimestamp 等不同的设置器以及 当然 setObject)。但事实证明,这种方式很难用于大数据量的情况,因为在这种情况下 fastinsert 变得非常慢。 datainsert通过某个对象用Java内的数据填充创建的prepared statement com.mathworks.toolbox.database.writeTheData class。这个class实现了两个方法——doubleWritecellWritedoubleWrite 允许用数字标量数据填充准备好的语句。 cellWrite 假设数据作为一个单元格矩阵传递,每个单元格中都有一个标量对象(对象可以是数字、逻辑 Matlab 标量、Matlab 字符串或 Java 支持的标量对象 JDBC 驱动程序,例如,org.postgresql.jdbc.PgArray 在数组的情况下)对于 相应的字段和元组。因此,不是从 Matlab 调用 setObject(这可能会导致 一个显着的开销)作为第一步,用必要的对象填充提到的单元格矩阵更有效 然后从 Matlab Database Toolbox 调用 datainsert 作为第二步。

数据插入方法的性能

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

此处fastinsertdatainsert的性能与batchParamExec的性能进行比较 来自 PgMex(有关详细信息,请参阅 https://pgmex.alliedtesting.com/#batchparamexec)。第一张图片是标量数值数据的情况,第二张图片是数组的情况。每个图的端点对应 到一定的最大数据量通过相应的方法无误的传入数据库。 数据量大于最大值(特定于每种方法)会导致“Java 堆内存不足”问题 (Java 每个实验的堆大小在每个图的顶部指定)。 更多实验详情请见下文 paper with full benchmarking results for data insertion.

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