将 Matlab 数组存储在 SQL Server varbinary 字段中

Posted

技术标签:

【中文标题】将 Matlab 数组存储在 SQL Server varbinary 字段中【英文标题】:Store Matlab array in a SQL Server varbinary field 【发布时间】:2012-06-13 18:29:57 【问题描述】:

有谁知道如何在 Microsoft SQL Server 的表的单个字段中存储一维 Matlab 数组(以及如何检索它)?我希望能够存储不一定是固定大小的 Matlab 数据数组,并且我考虑将其存储为逗号分隔的字符串,但我希望有一个更优雅的解决方案。我的想法是它应该与存储和读取一个字节[]相同。但是,我已经尝试了几个小时,但无法在互联网上找到任何真正有用的东西。这是我用于存储数组的 Matlab 代码(使用 ADO):

buf = [1,2,3,4,5]; 
buf = int8(buf);
cmd = actxserver('ADODB.Command');
cmd.ActiveConnection = db.connection; % db.connection stores my connection
% Note that Matlab throws an error when setting the ActiveConnection. This
% command is still valid though and works, so the error should be ignored

cmd.CommandText = 'INSERT INTO dbo.TESTTABLE VALUES(?)'; % According to the MSDN
% website, this should be @val instead of ?, but for some reason that doesn't 
% work and the ? does.

param = cmd.CreateParameter(@val',205,1,8000,buf);
cmd.Parameters.Append(param);
cmd.Execute();

可能是这段代码是正确的,我只是不知道如何再读一遍。另外,我举了一个大小为 5 的数组作为示例,但我希望能够存储更大的数组。 谢谢你的帮助,

麦迪

【问题讨论】:

好吧,我知道我以前看到过类似的问题,刚刚找到它:easiest way to serialize multi-dimensional array in MATLAB for database insertion?。 【参考方案1】:

您可以使用 TYPECAST 将矩阵序列化为字节向量 (uint8),并将结果与​​原始矩阵大小和类型一起存储在数据库中。

考虑以下示例。我使用的是文件而不是数据库,但这个想法仍然适用。

%# some matrix, and record its size and type
x = rand(4,3);
sz = size(x);
cls = class(x);

%# serialize and write to file
b = typecast(x(:),'uint8');          %# byte array
fid = fopen('file.dat','wb');
fwrite(fid, b, 'uint8')
fclose(fid);

%# read file and deserialize
fid = fopen('file.dat','rb');
b = fread(fid, '*uint8');
fclose(fid);
xx = reshape(typecast(b,cls), sz);

%# compare against original matrix
isequal(x,xx)

在上面我只存储序列化的数据,但你也应该存储大小和类型。在您的情况下,只需在表中创建两个附加字段,例如,一个用于大小,另一个用于类型..


如here 所述,如果您不想手动对矩阵及其大小/类型进行序列化,libmx 中有未记录的函数mxSerialize/mxDeserialize。 comments 中甚至还有一个指向简单 MEX 包装器的链接。

它们的优点是它们适用于任何 MATLAB 数据类型(包括结构体、元胞数组等)

【讨论】:

能够肯定地使用内置的序列化函数会很好,但是当我加载 libmx 并尝试使用它们时,Matlab 抱怨它们不存在。感谢你的回复;你教会了我一些关于类型转换的知识,这可能会解决问题。 @MaddieLowe:您必须获取两个 C 文件并将它们编译为 MEX 函数(我提到的评论中提供了 C 文件的链接)。请注意,它们是未记录的函数。【参考方案2】:

SQL 表中列的类型应该是二进制。然后只需使用常规的 mat lab 一维数组并尝试将它们导出到数据库。

您不需要任何逗号或任何额外的东西。它们由 Matlab 库手持。

例如你可以这样做:

colnames = 'ContentBinary' ; %this is the name of the column with the binary %content
data =   [1:100000]; % a one-d array in matlab
tablename = 'myData';
whereclause = 'where Id = 4028'; %this shows which row you are trying to write to
update(conn,tablename,colnames,data,whereclause)
close(conn); %conn is the connection to SQL DB

【讨论】:

【参考方案3】:

对于那些正在尝试类似问题的人,我找到了一种有效的方法。我在问题中发布的代码对于将字节数组从 Matlab 存储到 MS SQL Server 数据库中是正确的。不过,您应该知道,我将它存储到 VARBINARY(MAX) 的字段中,并且它会自动存储为无符号。此外,它只会存储一个类似的数组 buf = [1,2,3,4,5] 并且只会存储和数组的第一个值,就像 buf = [1;2;3;4;5]

当您检索它时,例如在 ADO 记录集中,您必须将其转换回 int8,这可以像 Amro 的回答中那样完成。

关于序列化,我写了一个简单的 Java 类,它实现了 Serializable 将对象转换为字节数组,反之亦然。由于可以从 Matlab 调用 Java,所以这个方法效果很好,现在我可以在 varbinary 列中存储和检索任何 Matlab 向量、数组或字符串。

【讨论】:

以上是关于将 Matlab 数组存储在 SQL Server varbinary 字段中的主要内容,如果未能解决你的问题,请参考以下文章

如何将数组传递到 SQL Server 存储过程

将对象数组分解为用于数据库存储的单独变量(React、express、sql server)

是否可以在 Sql Server 中使用整数数组参数创建 sp? [复制]

如何在 SQL Server 2005 中插入值数组?

解析 SQL Server 查询而不针对数据库连接执行查询 [重复]

使用matlab将音频信号存储到数组中