Ошибка при внесении данных в таблицу 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 шт):

Автор решения: emmagomedov

Есть так же проблема в типах данных, вы используете 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});";
→ Ссылка
Автор решения: rotabor

Скорее всего, каждый из limitParams.MinValue.ToString() и limitParams.MaxValue.ToString() выдаёт число с запятой в качестве десятичного разделителя, что воспринимается как два параметра вместо одного числа.

Чтобы получить строковое представление числа с десятичной точкой, используйте:

using System.Globalization;
...
    NumberFormatInfo nfi = new NumberFormatInfo() { NumberDecimalSeparator = "." };
    limitParams.MinValue.ToString(nfi);
    limitParams.MaxValue.ToString(nfi);

→ Ссылка
Автор решения: aepot

Никогда не используйте конкатенацию строк для формирования запроса. Это во-первых небезопасно, во-вторых можно натворить синтаксических ошибок. Откуда гарантии, что ни в одной из ваших строк нет запятых? В кавычки строки надо брать в самом запросе.

А более верным решением будет использовать запрос с параметрами, и пусть библиотека 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, но я не проверял.

→ Ссылка