Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/11: Рейтинг темы: голосов - 11, средняя оценка - 5.00
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
.NET 4.x

SQLite3 запись данных

26.03.2019, 13:09. Показов 2166. Ответов 14
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
УВАЖАЕМЫЕ МОДЕРАТОРЫ!!!
у меня создана подобная тема в разделе Unity, но почитав что библиотека мультиплатформенная решил создать тему и здесь, так как способ решения могут подсказать люди не имеющие знакомство с Unity. Прошу не удалять тему, а соеденить, или из раздела Unity удалить.

Суть проблемы

Добрый вечер. Появилась ошибка о том, что база заблокирована.

Делал я так
Как я пытался подключиться

db_login.cs

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
private db_controller _dbctrl = new db_controller();
    public SqliteDataReader dataread;
    private string query;
 
//======================= тут у меня два поля и я проверяю логин и пароль, а потом админ это или юзер
 public void LoginToGo()
    {
        login = _login.captionText.text;
        pass = _pass.text.ToString();
 
        query = "SELECT id from users where users = '" + login + "' AND pass = '" + pass + "'";
        try
        {
            dataread = _dbctrl.ExecuteReader(query);
            if(dataread.HasRows & dataread != null)
            {
                while (dataread.Read())
                {
                    VerifyAdmin();
                    _dbctrl.Disconnect();
                }
                
            }
            else
            {
                errortxt.text = "Неверный логин или пароль, пожалуйста повторите!";
            }
        }
        catch (Exception ex) { errortxt.text = ex.ToString(); }
    }
 
 public void VerifyAdmin() //========== собственно Сам метод проверки админ ты или юзер
    {
        login = _login.captionText.text;
 
 
        query_access = "SELECT root from users where users = '" + login + "'";
        try
        {
            dataread = _dbctrl.ExecuteReader(query_access);
              while (dataread.Read())
               {
                if(dataread[0].ToString() == "0" || dataread[0].ToString() == null)
                {
                    MainMenu();
                   
                }
                else
                    {
                    AdminMenu();
                    
                }
               }
              
        }
        catch (Exception ex) { errortxt.text = ex.ToString(); }
    }
 
 
//После того как я проверил что админ это админ, а юзер это юзер, я открываю для каждого своё меню
Всё работает хорошо.
Но вот потом всё обрывается ошибкой.
db_controller.cs


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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
public SqliteConnection con_db;
    public SqliteCommand cmd_db;
    public SqliteDataReader rdr_db;
 
//Тут я создаю метод подключения
public void connections()
    {
 
        try
        {
 
            if(Application.platform != RuntimePlatform.Android)
            {
                path = Application.dataPath + "/StreamingAssets/db.bytes"; // Путь для Windows
            }
            else
            {
                path = Application.persistentDataPath + "/db.bytes"; // Путь для Android
                if(!File.Exists(path))
                {
                    
                     WWW load = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "db.bytes");
                     while (!load.isDone) { }
                     File.WriteAllBytes(path, load.bytes);
                }
            }
        
        con_db = new SqliteConnection("URI=file:" + path);
        con_db.Open();
        if (con_db.State == ConnectionState.Open)
            {
               
                debugText.text = path.ToString() + " - is connected";
                Debug.Log(path.ToString());
                
            }
     
        }
        catch (Exception ex)
        {
            debugText.text = ex.ToString();
        }
    }
 
//Тут я создаю метод отключения
 public void Disconnect()
    {
        
        con_db.Close();
    }
 
 public SqliteDataReader ExecuteReader(string query)
    {
        connections();
        try
        {
            cmd_db = new SqliteCommand(query, con_db);
            rdr_db = cmd_db.ExecuteReader();
            return rdr_db;
        }
        catch (Exception ex) { debugText.text = ex.ToString(); return null; }
    }
 
//Тут я записываю данные. Заодно решил проверить закрыто ли соединение.
 
 public void SetDB()
    {
        
        if (con_db.State == ConnectionState.Open)
        {
            Debug.Log("Соединение ещё открыто");
        }
        else
        {
            Debug.Log("Соединение ЗАКРЫТО!");
        }
//Соединение закрыто. Но я не могу выполнить запрос cmd_db.ExecuteNonQuery();
        connections();
        try
        {
            brand = AutoName.captionText.text;
            model = AutoModel.captionText.text;
            years = OldAuto.captionText.text;
            number = GosNumber.text.ToString();
            nusers = UserName.text.ToString();
            dbirthday = DBirthday.captionText.text;
            mbirthday = MBirthday.captionText.text;
            ybirthday = YBirthday.captionText.text;
            mobile = Mobile.text.ToString();
            cmd_db = new SqliteCommand("INSERT INTO clients(brand,model,years,number,nusers,dbirthday,mbirthday,ybirthday,mobile,groupmodel) values('" + brand + "', '" + model + "','" + years + "','" + number + "','" + nusers + "','" + dbirthday + "','" + mbirthday + "','" + ybirthday + "','" + mobile + "','" +groupmodel+ "')" , con_db);
            cmd_db.ExecuteNonQuery(); //Ругается, говорит что база заблокирована. А почему? я же просто считал данные и соединение закрыл. 
// ОФ. документация говорит :
/*Этот код ошибки возникает, когда вы пытаетесь сделать две несовместимые вещи с базой данных одновременно из одного и того же соединения с базой данных*/
        }
        catch (Exception ex)  { debugText.text = ex.ToString(); }
        Disconnect();
    }


Никак не могу понять почему не обрабатывается запрос

У меня есть метод

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public SqliteDataReader ExecuteReader(string query)
    {
        connections(); // тут всё ровно
        try
        {
            cmd_db = new SqliteCommand(query, con_db);
            rdr_db = cmd_db.ExecuteReader();
            if (rdr_db.HasRows)
            {
                return rdr_db;
            }
            else
            {
                rdr_db.Close();
                return null;
            }
            
        }
        catch (Exception ex) { debugText.text = ex.ToString(); return null; }
    }
Но при добавлении нового пользователя получаю ошибку.

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
private db_controller _dbctrl = new db_controller();
private SqliteDataReader dr;
 
public void AddNewUser()
    {
        try
        {
            Login = _Login.text;
            Pass = _Pass.text;
            query = "INSERT INTO users(id,users,pass,root) values('4','" + Login + "','" + Pass + "','0')";
            queryCheck = "Select users from users where users='" +Login+"'";
            if (Login != "")
            {         
                dr = _dbctrl.ExecuteReader(queryCheck);
                Debug.Log(_dbctrl.con_db.State.ToString() + " - 1");
                if (dr==null)
                {
                    Debug.Log(_dbctrl.con_db.State.ToString() + " - 2");
                    _dbctrl.UpdateData(query);
                    TxtLogging.text = "Пользователь " + Login + " успешно добавлен";
                    Debug.Log(_dbctrl.con_db.State.ToString() + " - 3"); // Debug.Log это лог информации. 
                }
                else
                {
                    _dbctrl.Disconnect();
                    Debug.Log("Пользователь с ником" + Login + " уже существует");
                }
                
            }
            else { Debug.Log("Вы не ввели имя"); }
        }
        catch (Exception ex) { Debug.Log(ex.Message.ToString()); }
       
    }
Вот что читаю в логе
Code
1
2
3
4
5
6
7
8
Open - 1
UnityEngine.Debug:Log(Object)
Open - 2
UnityEngine.Debug:Log(Object)
The database file is locked
database is locked
Open - 3
UnityEngine.Debug:Log(Object)
Ошибка о закрытии базы говорит что поизочшла в этом методе

C#
1
2
3
4
5
6
7
8
9
10
11
12
public void UpdateData(string query)
    {
        connections();
        try
        {
            cmd_db = new SqliteCommand(query, con_db);
            cmd_db.ExecuteNonQuery();
            Disconnect();
            cmd_db.Dispose();
        }
        catch (Exception ex) { Debug.Log(ex.Message.ToString()); }
    }
Почему не выполняется метод ExecuteNonQuery(); ?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.03.2019, 13:09
Ответы с готовыми решениями:

Как ускорить запись данных в базу данных?
Добрый день. Есть следующий тестовый код: class MyClass { public int a; public int b; public int c; } void main()

Чтение данных из SQLite3 DB
Приветствую всех) Пишу небольшую программу для своих нужд, которая считывает заданные таблицы из SQLite3 DB файла и выводит в консоль. ...

Не получается считать данные с база данных db (библиотека SQLite3)
Cделал программу по исходникам из курсовой работы, формы запускают, но почему-то не все формы подключаются к базе, а последнее время вообще...

14
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 04:52
Цитата Сообщение от anomal6 Посмотреть сообщение
Почему не выполняется метод ExecuteNonQuery(); ?
У вас в логах это прямо сказано:

Цитата Сообщение от anomal6 Посмотреть сообщение
Open - 1
UnityEngine.Debug:Log(Object)
Open - 2
UnityEngine.Debug:Log(Object)
The database file is locked
database is locked

Open - 3
UnityEngine.Debug:Log(Object)
Файл базы заблокирован другим соединением. Либо вы в несколько потоков ломитесь к файлу базы, либо не закрываете соединения с базой.

Правильный алгоритм работы с СУБД такой: открыли соединение, взяли из базы что нужно, закрыли соединение. Удерживать соединение открытым не нужно (разве, что вы знаете заранее, что у вас несколько обращений подряд будет).
1
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 07:14  [ТС]
Спасибо Usaga , я только понять не могу где я не закрыл соединение.
Видимо придётся переписать всё, и использовать using
думаю это будет правильно. И while надо исключить.

примерно так
C#
1
2
3
4
5
6
7
using (SqliteCommand command = new SqliteCommand(sql, connection))
        {
            foreach (SqliteParameter param in args)
                command.Parameters.Add(param);
            command.ExecuteNonQuery();
        }
    }
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 07:20
anomal6, это только задиспозит объект команды. Само соединение в connection и его тоже нужно закрывать.
0
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 07:28  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Само соединение в connection и его тоже нужно закрывать
Тогда я не пойму как метод
C#
1
Connection()
правильно сделать.

то есть у меня есть метод и в конце его нужно закрыть?
Тогда весь смысл метода теряется.
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
public void connections()
    {
        try
        {
            if(Application.platform != RuntimePlatform.Android)
            {
                path = Application.dataPath + "/StreamingAssets/db.bytes"; // Путь для Windows
            }
            else
            {
                path = Application.persistentDataPath + "/db.bytes"; // Путь для Android
                if(!File.Exists(path))
                {                   
                     WWW load = new WWW("jar:file://" + Application.dataPath + "!/assets/" + "db.bytes");
                     while (!load.isDone) { }
                     File.WriteAllBytes(path, load.bytes);
                }
            }
        con_db = new SqliteConnection("URI=file:" + path);
        con_db.Open();
        if (con_db.State == ConnectionState.Open)
            {
                DebugLogText.debugText.text = path.ToString() + " - is connected";  
            }
        }
        catch (Exception ex)
        {
            Debug.Log(ex.ToString());
        }
//МНЕ ТУТ ЕГО ЗАКРЫТЬ НАДО?
    }
И принципиально ил чтобы база для андроида называлась *.bytes?
Видел пример который работает тоже хорошо.
C#
1
2
3
4
5
6
7
#if UNITY_EDITOR
    static string path = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "Database.sqlite");
#elif UNITY_ANDROID
    static string path = Path.Combine(Application.persistentDataPath, "Database.sqlite");
#else
    static string path = Path.Combine(Application.dataPath, "Database.sqlite");
#endif
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 07:30
anomal6, этот блевотного вида метод только открывает подключение. После использования этого подключения, его нужно явно закрыть.

Не по теме:

Смотреть на такой код больно.



Причём, методу лучше возвращать подключение, а не хранить его как поле класса.
1
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 07:43  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
anomal6, этот блевотного вида метод только открывает подключение. После использования этого подключения, его нужно явно закрыть.
Не по теме:
Смотреть на такой код больно.
Причём, методу лучше возвращать подключение, а не хранить его как поле класса.
я правильно Вас понял?
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
public class db_connection : MonoBehaviour {
 
    public SqliteConnection sqlCon;
    public SqliteCommand sqlCmd;
    public SqliteDataReader sqlRdr;
#if UNITY_EDITOR
    static string path = Path.Combine(Directory.GetParent(Application.dataPath).FullName, "Database.sqlite");
#elif UNITY_ANDROID
    static string path = Path.Combine(Application.persistentDataPath, "Database.sqlite");
#else
    static string path = Path.Combine(Application.dataPath, "Database.sqlite");
#endif
    public void connections(SqliteConnection SQL_connection)
    {
        try
        {
            SQL_connection = new SqliteConnection("URI=file:" + path);
            SQL_connection.Open();
        }
        catch (Exception ex)
        {
            Debug.Log(ex.ToString());
        }
    }
 
    void Start()
    {
        connections(sqlCon);
    }
}
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 07:47
Лучший ответ Сообщение было отмечено anomal6 как решение

Решение

anomal6, нет, не правильно.

Сформируйте строку подключения один раз, сохраните её в доступном в коде месте (класс с настройками). Создавайте подключение, каждый раз новое, не надо его сохранять в виде поля класса. Возвращайте объект подключения из метода его создающего. Закрывайте или освобождайте (Dispose, Using) этот объект подключения, когда он вам становится не нужен.
1
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 07:53  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
Возвращайте объект подключения из метода его создающего
не совсем могу понять что Вы мне советуете. Объект подключения это БД, как мне его возвратить?
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 07:54
anomal6,

C#
1
2
3
4
5
6
    public SqliteConnection GetConnection()
    {
        var connection = new SqliteConnection(connectionString);
        connection.Open();
        return connection;
    }
1
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 08:02  [ТС]
Спасибо Usaga.

А я вот возвратил подключение, получается оно открытое уже возвращается, и будет открытым пока я его не закрою ручками?
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 08:59
anomal6, да, именно так.
0
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 09:48  [ТС]
Цитата Сообщение от Usaga Посмотреть сообщение
да, именно так.
Но теперь db_connection
C#
1
2
3
4
5
6
7
8
9
10
public class db_connection : MonoBehaviour {
    string path = Application.dataPath + "/StreamingAssets/db.bytes"; // Путь для Windows
    
    public SqliteConnection GetConnection()
    {
        var connection = new SqliteConnection("URI=file:" + path);
        connection.Open();
        return connection;  
    }
}
db_controller
C#
1
2
3
4
5
6
7
8
9
10
11
12
    public SqliteCommand cmd_db;
    public SqliteDataReader rdr_db;
void Awake()
    {
        db_connection DBCON = new db_connection();
        DBCON.GetConnection();
    }
 
    void Start () {     
        cmd_db = new SqliteCommand("Select * from users", con_db);
        rdr_db = cmd_db.ExecuteReader(); //No connection associated with this command
    }
Теперь говорит "нет соединения, связанного с этой командой."
0
Эксперт .NET
 Аватар для Usaga
14138 / 9362 / 1350
Регистрация: 21.01.2016
Сообщений: 35,197
27.03.2019, 09:54
anomal6, вы методом тыка пишите, чтоли?) Вы метод вызвали, а значение, что он возвращает, вы в гробу видали?)
0
95 / 62 / 22
Регистрация: 11.03.2013
Сообщений: 608
Записей в блоге: 7
27.03.2019, 09:54  [ТС]
Вот же я башка тупая
C#
1
2
3
db_connection DBCON = new db_connection();
        DBCON.GetConnection();
        cmd_db = new SqliteCommand("Select * from users", DBCON.GetConnection());
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.03.2019, 09:54
Помогаю со студенческими работами здесь

Запись данных в базу данных mdb с использованием DataAdapter и DataSet
Попробовал сделать Update для таблицы контактов: private void Form1_Load(object sender, EventArgs e) { OleDbConnection...

Запись данных в базу данных SQL и выгрузка таблицы в форму
Нужно сделать 2 формы, одну с несколькими textBox'ами, чтобы при нажатии кнопки информация введённая в них, записывалась в Базу данных, и...

Sqlite3 не работает на Windows 10
Проблема с Sqlite3, на Windows 7 работает, а на W10 нет, использую sqlite3.dll

Некорректное отображение кириллицы при выборке из SQLIte3
Добрый день, уважаемые форумчане. Долгое время работала с С++. Теперь осваиваю С# в связке с SQLite3. Возникла проблема, казалось...

Не добавляется ссылка на Sqlite3 DLL
Скрин ошибки:


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru