Matlab数据库编写语句和绑定变量

时间:2016-01-15 09:52:58

标签: database matlab sql-injection

我对Matlab很新,但是我已经成功地使用它与数据库交互(在我的情况下是PostgreSQL),遵循关于如何connect to a database using JDBC drivers的官方文档,然后是{{3} }。但是,在后一种情况下给出的示例涉及将数据粘贴到查询中,这可能是低效的并且对SQL注入开放。

我真正想做的是使用绑定变量,例如在executing a query with exec中完成的。我在文档中找不到任何相关内容。有没有办法做到这一点?

2 个答案:

答案 0 :(得分:6)

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

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

实际上,这个工具箱通过直接JDBC连接与PostgreSQL一起使用。此外,两种实现的数据插入方法datainsertfastinsert都通过专门创建的预处理语句来工作。这两者之间的唯一区别在于各自准备好的陈述充满了数据。 fastinsert通过使用您提到的完全相同的技术(通过使用setDoublesetBooleansetTimestamp等不同的设置工具在Matlab中执行此操作 当然setObject)。但事实证明,这种方式在大数据量的情况下很难使用,因为在这种情况下fastinsert变得非常慢。 datainsert通过Java的某个对象用Java中的数据填充创建的预准备语句 com.mathworks.toolbox.database.writeTheData课程。该类实现了两种方法 - doubleWritecellWritedoubleWrite允许使用数字标量数据填充预准备语句。 cellWrite假设数据作为单元格矩阵传递,每个单元格中有一个标量对象(对象是数字,逻辑Matlab标量,Matlab字符串或JDBC驱动程序支持的标量Java对象,比方说,对于数组而言,org.postgresql.jdbc.PgArray 相应的字段和元组。因此,而不是从Matlab调用setObject(这可能会导致 作为第一步,用所需的对象填充所提到的单元矩阵更有效 然后从Matlab数据库工具箱中调用datainsert作为第二步。

数据插入方法的性能

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

The case of scalar numeric data The case of arrays

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

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

答案 1 :(得分:5)

看起来我已经设法回答了我自己的问题,所以我分享了这份爱。 AFAICS数据库工具箱非常基础,但幸运的是,我可以直接使用Java的JDBC API,因为我在支持团队对this question的响应中进行了查看。

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

    String command = "cmd /c start cmd.exe";
    Process child = Runtime.getRuntime().exec(command);
    OutputStream output = child.getOutputStream();

    output .write("cd C:/ /r/n".getBytes());
    output .flush();
    output .write("DIR /r/n".getBytes());
    output .close();