Ошибка при внесении данных в таблицу SQLite
В базе данных SQLite есть следующая таблица:
CREATE TABLE "LimitParams" (
"id" INTEGER NOT NULL UNIQUE,
"signalId" INTEGER NOT NULL,
"startDate" INTEGER NOT NULL,
"endDate" INTEGER NOT NULL,
"minValue" REAL NOT NULL,
"maxValue" REAL NOT NULL,
PRIMARY KEY("id" AUTOINCREMENT)
);
В программе имеется класс LimitParamsModel
public class LimitParamsModel
{
public int Id { get; set; }
public int SignalId { get; set; }
public TimeSpan StartDate { get; set; }
public TimeSpan EndDate { get; set; }
public float MinValue { get; set; }
public float MaxValue { get; set; }
}
Я пытаюсь выполнить следующий запрос на вставку данных:
"Insert into LimitParams (signalId, startDate, endDate, minValue, maxValue) VALUES(" + (limitParams.SignalId.ToString()) + ", " + (limitParams.StartDate.Ticks.ToString()) + ", " + (limitParams.EndDate.Ticks.ToString()) + ", " + (limitParams.MinValue.ToString()) + ", " + (limitParams.MaxValue.ToString()) + ")";
При этом я получаю исключение:
{"SQLite Error 1: '7 values for 5 columns'."}
Почему такое может происходить?
Ответы (3 шт):
Есть так же проблема в типах данных, вы используете TimeSpan для StartDate и EndDate, тогда как в базе данных SQLite у вас тип данных INTEGER для этих столбцов. Попробуйте так
string query = $"INSERT INTO LimitParams (signalId, startDate, endDate, minValue, maxValue) VALUES ({limitParams.SignalId}, {limitParams.StartDate.Ticks}, {limitParams.EndDate.Ticks}, {limitParams.MinValue}, {limitParams.MaxValue});";
Скорее всего, каждый из limitParams.MinValue.ToString() и limitParams.MaxValue.ToString() выдаёт число с запятой в качестве десятичного разделителя, что воспринимается как два параметра вместо одного числа.
Чтобы получить строковое представление числа с десятичной точкой, используйте:
using System.Globalization;
...
NumberFormatInfo nfi = new NumberFormatInfo() { NumberDecimalSeparator = "." };
limitParams.MinValue.ToString(nfi);
limitParams.MaxValue.ToString(nfi);
Никогда не используйте конкатенацию строк для формирования запроса. Это во-первых небезопасно, во-вторых можно натворить синтаксических ошибок. Откуда гарантии, что ни в одной из ваших строк нет запятых? В кавычки строки надо брать в самом запросе.
А более верным решением будет использовать запрос с параметрами, и пусть библиотека Microsoft.Data.Sqlite сама решает, как правильнее передать данные в БД, а не вы. Нужно лишь указать, какой именно тип данных ожидает база с помощью перечисления DbType.
using var connection = new SqliteConnection(connectionString);
connection.Open();
var command = connection.CreateCommand();
command.Text = "INSERT INTO LimitParams (signalId, startDate, endDate, minValue, maxValue) VALUES ($signalId, $startDate, $endDate, $minValue, $maxValue)";
command.Parameters.Add("$signalId", DbType.Int32).Value = limitParams.SignalId;
command.Parameters.Add("$startDate", DbType.Int64).Value = limitParams.StartDate.Ticks;
command.Parameters.Add("$endDate", DbType.Int64).Value = limitParams.EndDate.Ticks;
command.Parameters.Add("$minValue", DbType.Single).Value = limitParams.MinValue;
command.Parameters.Add("$maxValue", DbType.Single).Value = limitParams.MaxValue;
command.ExecuteNonQuery();
Есть ещё перечисление SqliteType, попробуйте использовать его вместо DbType, но я не проверял.