2017-02-02 3 views
2

У меня есть база данных Microsoft Access в папке ресурсов моего приложения Java. Когда пользователь нажимает кнопку, эта база данных копируется в временную директорию ПК. Затем я создаю временный файл VBS в том же каталоге и выполняю его. (Этот файл VBS вызывает макрос VBA в базе данных, который удаляет некоторые записи.) Однако, когда макрос пытается удалить записи, возникает ошибка, указывающая, что база данных только для чтения. Почему это происходит?Почему файл доступен только для чтения?

Вот мой код:

Когда пользователь нажимает на кнопку, некоторые переменные установлены, а затем выполняется следующий код:

private void moveAccess() throws IOException { 
    String dbName = "sys_cl_imp.accdb"; 
    String tempDbPath = System.getenv("TEMP").replace('\\', '/') + "/" + dbName; 
    InputStream in = ConscriptioLegere.class.getResourceAsStream("res/" + dbName); 
    File f = new File(tempDbPath); 
    Files.copy(in, f.toPath(), StandardCopyOption.REPLACE_EXISTING); 

    this.dbFilePath = tempDbPath; 
    System.out.println("access in temp"); 
    f = null; 
} 

Затем соединение с базой данных, чтобы обновить некоторые данные; с

Connection con = DriverManager.getConnection("jdbc:ucanaccess://" + dbFilePath);    
Statement sql = con.createStatement(); 
... 
sql.close(); 
con.close(); 

После этого выполняется:

public boolean startImport() { 
    File vbsFile = new File(vbsFilePath); 
    PrintWriter pw; 
    try { 
     updateAccess(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     return false; 
    } 

    try{ 
     pw = new PrintWriter(vbsFile); 
     pw.println("Set accessApp = CreateObject(\"Access.Application\")"); 
     pw.println("accessApp.OpenCurrentDatabase (\"" + dbFilePath + "\")"); 
     pw.println("accessApp.Run \"sys_cl_imp.importData\", \"" + saveLoc + "\""); 
     pw.println("accessApp.CloseCurrentDatabase"); 
     pw.close(); 

     Process p = Runtime.getRuntime().exec("cscript /nologo \"" + vbsFilePath + "\""); 

В то время как процесс запущен, occurres ошибок. Я не понимаю, почему база данных открыта как ReadOnly.

Я попытался установить f на нуль после копирования db, но оказалось, что это не работает.

ответ

2

Основано на this dicussion.
Решение добавляет ;singleconnection=true к URL-адресу JDBC. UCanAccess закроет файл после закрытия соединения JDBC.

Connection con = DriverManager.getConnection("jdbc:ucanaccess://" + dbFilePath +";singleconnection=true"); 
+1

см. Дополнительный ответ для всего решения ... –

1

Благодарим за решение проблемы beckyang. Мне удалось заставить его работать с ним, но произошла вторая ошибка: Я удалил содержимое таблицы с помощью java, затем закрыл соединение и запустил процедуру vba. В VBA я снова пытался удалить данные; но так как их не было, это не сработало. После удаления SQL из VBA проект работал :)

Смежные вопросы