【问题标题】:Matlab create new Microsoft Access Database file *.accdbMatlab 创建新的 Microsoft Access 数据库文件 *.accdb
【发布时间】:2018-10-08 23:17:05
【问题描述】:

我使用以下代码模式来访问我的 *.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 来探索数据库。

【问题讨论】:

    标签: matlab ms-access database-connection


    【解决方案1】:

    实际上,您尝试做的事情可能很难实现。它可能需要通过ActiveX 控件直接访问访问接口,我什至不确定它是否可以完成。网络似乎缺乏关于 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
    

    【讨论】:

    • 再次感谢您,托马索。有了这么多的代码开销,在 Matlab 环境中使用 SQL 操作数据几乎没有吸引力。但是,它具有教育意义。根据您的最小工作示例,我花了一个下午的时间反复试验,敲定了一个示例,其中包括创建数据库表和导出 Matlab 表。
    【解决方案2】:

    以下示例基于 Tommaso 的回答,该回答提供了用于复制空的 *.accdb 文件并连接到副本的代码。基于一个下午的试验、错误、网络/帮助的细读,我对此进行了扩展,以创建一个数据库表并将一个 Matlab 表导出到它。我还嵌入了 cmets 来显示需要修改的地方,这可能是由于我的 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 函数的字段名称参数的用途的评论将不胜感激。它在 documentation 中被称为 colnames。通过测试,Access 中的现有目标表和 Matlab 中的源表之间的字段名称和列数必须匹配。所以字段名称参数似乎没有任何用途。帮助文档并不是那么有用。

    后记:我根据 TMW 的示例为 colnams 参数编写了一个“规范”。 TMW 已经证实了这个解释:

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

    如果我发现经验行为与上述“规范”有任何偏差,我将更新此答案。

    【讨论】:

      猜你喜欢
      • 2012-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多