Следующий пример основан на ответе Томмазо, который предоставляет код для копирования пустого файла *.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
.
Если я обнаружу какие-либо отклонения эмпирического поведения от вышеуказанной «спецификации», я обновлю этот ответ.