将 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 字段中的主要内容,如果未能解决你的问题,请参考以下文章
将对象数组分解为用于数据库存储的单独变量(React、express、sql server)
是否可以在 Sql Server 中使用整数数组参数创建 sp? [复制]