Matlab创建新的Microsoft Access数据库文件* .accdb

时间:2018-04-28 06:52:32

标签: matlab ms-access database-connection

我使用以下代码模式来访问我的* .accdb文件:

accdb_path='C:\path\to\accdb\file\wbe3.accdb';
accdb_url= [ 'jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='''';DBQ=' accdb_path ];
conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);

如果我想创建一个新的* .accdb文件,我该怎么做?网上有很多关于如何连接的内容,但我还没有找到如何创建* .accdb文件本身。

如果重要,我希望能够执行SQL 92语法。我正在使用Matlab 2015b。我不想使用Matlab GUI来浏览数据库。

2 个答案:

答案 0 :(得分:1)

实际上,您尝试做的事情可能非常棘手。它可能需要通过ActiveX控件直接访问Access,我甚至不确定是否可以完成。似乎网络缺乏关于Access互操作性的可靠信息池。

一个快速的解决方法我可以建议你,通过悲惨的方法,手动创建一个空的ACCDB文件,您可以将其用作模板,然后在必须创建新数据库时复制它:

conn = CreateDB('C:\PathB\wbe3.accdb');

function accdb_conn = CreateDB(accdb_path)
    status = copyfile('C:\PathA\template.accdb',accdb_path,'f');

    if (status)
        accdb_url = ['jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='';DBQ=' accdb_path];
        accdb_conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);
    else
        accdb_conn = [];
        error(['Could not duplicate the ACCDB template to the directory "' accdb_path '".']);
    end
end

答案 1 :(得分:1)

以下示例基于Tommaso的答案,该答案提供了复制空*.accdb文件并连接到副本的代码。基于下午的试验,错误,浏览网页/帮助,我扩展了它以创建一个数据库表并导出一个Matlab表。我还嵌入了评论,显示需要进行修改的地方,可能是由于我的旧版2015b版Matlab,错误捕获结构以及文件副本中的警告。

srcPath = [pwd '/emptyFile.accdb'];    % Source
tgtPath = [pwd '/new.accdb'];          % Target
cpyStatOk = copyfile( srcPath, tgtPath );
   % No warning B4 clobber target file

if cpyStatOk
   accdb_url= [ ...
      'jdbc:odbc:Driver={Microsoft Access Driver (*.mdb, *.accdb)};DSN='''';DBQ=' ...
      tgtPath ];
   conn = database('','','','sun.jdbc.odbc.JdbcOdbcDriver',accdb_url);
else
   error('Couldn''t copy %s to %s',srcPath,tgtPath);
end % if cpyStatOk

try

   % conn.Execute(['CREATE TABLE tstMLtbl2accdb ' ... Not for 2015b
   curs = conn.exec(['CREATE TABLE tstMLtbl2accdb ' ...
                     '( NumCol INTEGER, StrCol VARCHAR(255) );']);

   if ~isempty( curs.Message )
      % fprintf(2,'%s: %s\n',mfilename,curs.Message);
      error('%s: %s\n',mfilename,curs.Message);
         % Trigger `catch` & close(conn)
   end %if

   % sqlwrite( conn, 'tstMLtbl2accdb', ...Not supported in 2015b
   datainsert( conn, 'tstMLtbl2accdb', {'NumCol','StrCol'}, ...
      table( floor(10*rand(5,1)), {'abba';'cadabra';'dog';'cat';'mouse'}, ...
             'VariableNames',{'NumCol','StrCol'} ) );

catch xcptn

   close(conn)
   fprintf(2,'Done `catch xcptn`\n');
   rethrow(xcptn);

end % try

%
%  Other database manipulations here
%

close(conn)
disp(['Done ' mfilename]);

这对我自己来说非常有教育意义,我希望对于其他考虑使用SQL作为代码密集型Matlab对应关系数据库操作的替代方案的人来说,它是有用的。有了这么多的开销,我不得不说对Matlab工作空间中的数据执行SQL操作是没有吸引力的,除非真正需要关系数据库查询引擎的超优化。

对于那些与Access接口的人来说,您对datainsert函数的字段名称参数的目的的评论将会受到赞赏。在其中被称为colnames documentation。从测试开始,字段名称和列数必须匹配Access中的现有目标表和Matlab中的源表。因此,字段名称参数似乎没有任何用途。帮助文档并没有那么有用。

AFTERNOTE:我根据TMW的例子为colnams参数编写了一个“规范”。 TMW证实了这一解释:

  

colnames参数告诉外部数据库环境通过data参数提供的数据容器的名称和字段顺序。这些字段名称用于将传输数据的字段与驻留在外部数据库环境中的表tablename中的字段进行匹配。由于此显式名称匹配,data中字段的顺序不必与tablename中字段的顺序相匹配。

如果我发现任何偏离上述“规范”的经验行为,我会更新这个答案。