Форум программистов, компьютерный форум, киберфорум
SQLite
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696

C API, sqlite. Держит открытым файловый handle после закрытия базы данных

28.08.2019, 20:39. Показов 1115. Ответов 0

Студворк — интернет-сервис помощи студентам
Доброго вечера.

Есть база данных и C++ программа для работы с ней. Я упростил пример до минимального. Подготавливается statement, биндятся значения, потом делается step. После этого на statement делаю reset и clear_bindings, чтобы заново его переиспользовать. Потом снова запускаю prepare, bind, step. Дальше finalize на statement и close базы данных.
Проблема в том, что, если в программе переиспользуется statement, то не смотря на то, что finalize и close возвращают OK, файловый хэндл на файл базы данных все еще остается открытым. И это мешает выполнить ее удаление на Windows. Я никак не могу понять, как правильно заиспользовать reset, чтобы мочь переиспользовать один и тот же statement несколько раз, чтобы после закрытия базы данных, sqlite закрывал файловый дескриптор. Сам пример кода:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
#include <Windows.h>
#include <sqlite3.h>
 
int main()
{
  sqlite3 *db;
  sqlite3_stmt *res;
 
  int rc = sqlite3_open("test.db", &db);
 
  if (rc != SQLITE_OK) {
 
    std::cout<<"Cannot open database: "<<sqlite3_errmsg(db);
    sqlite3_close(db);
 
    return 1;
  }
 
  sqlite3_exec(db, "create table Cars(Id INTEGER, Name TEXT);", nullptr, nullptr, nullptr);
  sqlite3_exec(db, "insert into Cars(Id, Name) values(1, \"nissan\");", nullptr, nullptr, nullptr);
  sqlite3_exec(db, "insert into Cars(Id, Name) values(2, \"kia\");", nullptr, nullptr, nullptr);
 
  rc = sqlite3_prepare_v2(db, "insert into Cars(Id, Name) values(3, ?1);" , -1, &res, 0);
  if( rc != SQLITE_OK)
    std::cerr << "\n\n NOT PREPARED! \n\n";
 
  sqlite3_bind_text(res, 1, "hyndai", -1, nullptr);
  if (sqlite3_step(res) == SQLITE_DONE)
  {
    std::cout << "\n\nINSERTED!\n\n";
    sqlite3_clear_bindings(res);
    if (SQLITE_OK != sqlite3_reset(res))
      std::cerr << "\n\n ERROR reset\n\n";
  }
 
  const char *sql = "SELECT Id, Name FROM Cars WHERE Id < ?";
 
  rc = sqlite3_prepare_v2(db, sql, -1, &res, 0);
 
  if (rc == SQLITE_OK)
    sqlite3_bind_int(res, 1, 5);
  else
    std::cout<<"Failed to prepare statement: "<<sqlite3_errmsg(db);
 
 
  if (SQLITE_OK != sqlite3_finalize(res))
  {
    std::cerr << "\n\n NOT FINALIZED! \n\n";
  }
 
  if (SQLITE_OK != sqlite3_close_v2(db))
  {
    std::cerr << "\n\n NOT CLOSED! \n\n";
  }
 
  if (0 == DeleteFile(L"test.db"))
    std::cerr << "Unable to remove the file." << std::endl;
 
  return 0;
}
После этого выполнения кода DeleteFile не работает из-за открытого дескриптора. Но, если убрать второй prepare, то все хорошо. Но, судя по документации, суть reset'а как раз в том, чтобы и давать возможность использовать один и тот же statement повторно.

Добавлено через 6 минут
Если использовать sqlite3_close, чтобы сразу поймать ошибку без ожидания финализаций, то будет сообщение об ошибке:
unable to close due to unfinalized statements or unfinished backups
Но почему? предыдущий finalize вернул OK. А самый первый prepare я зарезетил.

Добавлено через 5 минут
Все, я въехал после 10-го прочтения документации. sqilte3_reset не дает возможности подготовить новый запрос. Он только позволяет заново перезапустить подготовленный и поменять ему биндинги, но не сам запрос. Все, надо в отпуск.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.08.2019, 20:39
Ответы с готовыми решениями:

Считать содержимое BLOB поля из базы данных SQlite, используя API функций С/С++
Добрый день, необходимо корректно считать содержимое BLOB поля в программу и как-то удостовериться, что содержимое поля считано правильно. ...

Выгрузить MS Access после закрытия базы данных
Коллеги,помогите решить проблему. Закрываю приложение.В списке запущенных процессов висит MSACCESS. Внимательно проверил код приложения...

Поток держит файл открытым при завершении
private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { ((Button) sender).IsEnabled = false; ...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.08.2019, 20:39
Помогаю со студенческими работами здесь

Восстановить поврежденный файл базы данных SQLite (сделать дамп запароленного файла базы данных)
Вообщем не понятно после чего перестал открываться файл базы данных с ошибкой - &quot;database disk image is malformed&quot;. Нашел...

Не закрывается Access после закрытия базы
Закрываю базу, а Access остается открытым. Закрываю приложение диспетчером (тремя клавишами). В чем дело?

После закрытия и открытия базы ошибка полей в отчете #Имя?
Доброе время суток! После закрытия и открытия базы ошибка полей в отчете #Имя? Самое интересное, что проблема временно решается,...

Подскажите механизм закрытия базы данных
КАК ЛУЧШЕ ДЕЛАТЬ, ну или как делают? как положено? Открывать/закрывать при каждом запросе мне кажется плохо... или вообще можно и не...

Написать функции для считывания данных о выбранных сущностях из базы данных SQLite
Здравствуйте, помогите доделать программу. Надо написать функции для считывания данных о выбранных сущностях из базы данных SQLite. В...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru