Matlab создает новый файл базы данных Microsoft Access * .accdb - PullRequest
0 голосов
/ 28 апреля 2018

Я использовал следующий код для доступа к моим * .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 для исследования баз данных.

Ответы [ 2 ]

0 голосов
/ 29 апреля 2018

Следующий пример основан на ответе Томмазо, который предоставляет код для копирования пустого файла *.accdb и подключения к копии. Основываясь на пробной версии, ошибках, просмотре веб / справки, я подробно остановился на этом, чтобы создать таблицу базы данных и экспортировать в нее таблицу Matlab. Я также добавил комментарии, показывающие, где необходимо внести изменения, предположительно из-за моей более старой версии Matlab 2015b, конструкций с перехватом ошибок и предупреждений в копии файла.

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 для манипуляций с реляционными базами данных. При таком количестве накладных расходов я бы сказал, что нецелесообразно выполнять SQL-манипуляции с данными, находящимися в рабочем пространстве Matlab, за исключением тех случаев, когда действительно требуется гипероптимизация механизмов запросов реляционных баз данных.

Для тех, кто разбирается в интерфейсе с Access, ваш комментарий о назначении аргумента имен полей функции datainsert будет принят. В документации он дублирован colnames 1012 *. После тестирования имена полей и количество столбцов должны совпадать между существующей целевой таблицей в Access и исходной таблицей в Matlab. Таким образом, аргумент имен полей, похоже, не служит какой-либо цели. Справочная документация не так уж и полезна.

AFTERNOTE: Я составил «спецификацию» для аргумента colnams на основе примеров из TMW. TMW подтвердил это объяснение:

Аргумент colnames сообщает среде внешней базы данных имена и порядок полей контейнера данных, передаваемых через аргумент data. Эти имена полей используются для сопоставления полей передаваемых данных с полями в таблице tablename, находящимися в среде внешней базы данных. Из-за этого явного сопоставления имен порядок полей в data не обязательно должен совпадать с порядком полей в tablename.

Если я обнаружу какие-либо отклонения эмпирического поведения от вышеуказанной «спецификации», я обновлю этот ответ.

0 голосов
/ 28 апреля 2018

На самом деле, то, что вы пытаетесь сделать, может быть очень сложно достичь. Это может потребовать прямого интерфейса для доступа через 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
...