BASSIES Ответов: 3

Обновление десятичной дроби в базе данных sqlce


Привет,

У меня есть проблема с обновлением десятичного числа в базе данных sqlce.
База данных
Использование версии Visual studio и framework 3.5 2017 года

Numeric 18.3 and nulls allowd


<pre>cmd = New SqlCeCommand("Update Gegevens Set Kg ='" & Kg.Text & "' Where Id='" & Gegevensid.Text & "'", con)
        If con.State = ConnectionState.Closed Then con.Open()
        cmd.ExecuteNonQuery()
        If con.State = ConnectionState.Open Then con.Close()


Ошибка заключается в следующем

System.Data.SqlServerCe.SqlCeException
  HResult=0x80131501
  Message=Data conversion failed. [ OLE DB status value (if known) = 0 ]
  Source=SQL Server Compact ADO.NET Data Provider


Я могу сохранить номер в базе данных , но не обновлять .

Код, который я использовал много раз в другом проекте, но теперь ошибка ?

Что я упускаю из виду

Думаете, это означает, что в текстовом поле есть 0 ?

Что я уже пробовал:

Используйте код раньше, но теперь ошибка.

Когда я меняю его на другой столбец с Nvarchar , нет никаких проблем, он обновляется.

Bryian Tan

Попробуйте преобразовать в десятичное число перед обновлением.

3 Ответов

Рейтинг:
27

Patrice T

cmd = New SqlCeCommand("Update Gegevens Set Kg ='" & Kg.Text & "' Where Id='" & Gegevensid.Text & "'", con)

Не обязательно решение вашего вопроса, но у вас есть еще одна проблема.
Никогда не создавайте SQL-запрос путем объединения строк. Рано или поздно вы сделаете это с помощью пользовательских вводов, и это откроет дверь к уязвимости под названием "SQL-инъекция", она опасна для вашей базы данных и подвержена ошибкам.
Одна кавычка в имени - и ваша программа выйдет из строя. Если пользователь вводит имя, например "Брайан О'Коннер", может привести к сбою вашего приложения, это уязвимость SQL-инъекции, и сбой-это наименьшая из проблем, вредоносный пользовательский ввод, и он продвигается к командам SQL со всеми учетными данными.
SQL-инъекция - Википедия[^]
SQL-инъекция[^]
Атаки SQL-инъекций на примере[^]
PHP: SQL-инъекция - руководство пользователя[^]
Шпаргалка по предотвращению инъекций SQL - OWASP[^]
Как я могу объяснить SQL-инъекцию без технического жаргона? - Обмен Стеками Информационной Безопасности[^]


BASSIES

Спасибо за предупреждение,

И это сморщилось , у вас есть пример, хо я обновляю это .

Читаю что-то об этом, но не могу понять, что именно нужно изменить.


cmd = New SqlCeCommand("Update Gegevens Set Kg ='" & Kg.Текст & "' Where Id='" & Gegevensid.Текст & "'", con)

Patrice T

Чтобы понять, в чем проблема, вам нужно посмотреть, какую именно команду вы посылаете.
tmp="обновить набор Gegevens Kg ='" & Kg.Текст & "' Where Id='" & Gegevensid.Текст & "'"
cmd = новая команда SqlCeCommand(tmp, con)
и проверяйте tmp при ошибке.

BASSIES

Это работает или я неправильно читаю о sql-инъекции.

Другой пример с колонкой в Nvarchar , где она раньше сжималась, а теперь экономится

cmd = New SqlCeCommand("UPDATE Gevaren Set Vertrekvaren = @Vertrekvaren Where Id='" & Gevarenid.Текст & "'", con)
Если Кон.Состояние = ConnectionState.Закрыл тогда кон.Открыть()
cmd.Parameters.Add("@Vertrekvaren", SqlDbType.NVarChar).Значение = Vertrekvaren.Текст
УМК.Метод executenonquery()

BASSIES

OriginalGriff ,

Вы тоже Райт , но я был сосредоточен на обновлении и не понимал SQL-инъекции.

И да у меня есть проблема

BASSIES

Спасибо OriginalGriff и Patrice T ,

Узнав много нового с этим вопросом, я должен прочитать больше о SQL-инъекции.

Теперь это была маленькая вещь, чтобы изменить обновление так рано в моей программе.

Patrice T

Спасибо за ваши отзывы

Рейтинг:
2

BASSIES

cmd = New SqlCeCommand("UPDATE Cijfers Set Kg= @Kg Where Id='" & Cijfersid.Text & "'", con)
If con.State = ConnectionState.Closed Then con.Open()
cmd.Parameters.Add("@Kg", SqlDbType.Decimal).Value = Kg.Text
cmd.ExecuteNonQuery()


Patrice T

Использование второго параметра для Cijfersid.Текст действительно защитит вашу команду SQL.

BASSIES

Патрис Ти,

Вот так ?

команду cmd = новый SqlCeCommand("Cijfers обновление комплекта кг= @кг где ID = @ID в", кон)
Если Кон.Состояние = ConnectionState.Закрыл тогда кон.Открыть()
УМК.Параметры.Добавить("@Идентификатор", Значения Sqldbtype.Тип nvarchar).Значение = Cijfersid.Текст
cmd.Parameters.Add("@Kg", SqlDbType.Десятичный).Значение = Кг Текста
УМК.Метод executenonquery()

Рейтинг:
13

OriginalGriff

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

Когда вы объединяете строки, вы вызываете проблемы, потому что SQL получает такие команды, как:

SELECT * FROM MyTable WHERE StreetAddress = 'Baker's Wood'
Цитата, добавленная пользователем, завершает строку в том, что касается SQL, и вы получаете проблемы. Но могло быть и хуже. Если я приду и наберу вместо этого: "x';DROP TABLE MyTable;--", то SQL получит совсем другую команду:
SELECT * FROM MyTable WHERE StreetAddress = 'x';DROP TABLE MyTable;--'
Которые SQL видит как три отдельные команды:
SELECT * FROM MyTable WHERE StreetAddress = 'x';
Совершенно правильный выбор
DROP TABLE MyTable;
Вполне допустимая команда "удалить таблицу"
--'
А все остальное-это комментарии.
Так оно и происходит: выбирает любые совпадающие строки, удаляет таблицу из базы данных и игнорирует все остальное.

Поэтому всегда используйте параметризованные запросы! Или будьте готовы часто восстанавливать свою БД из резервной копии. Вы ведь регулярно делаете резервные копии, не так ли?

Начните с десятичной дроби.TryParse преобразует входные данные пользователя в десятичные значения - сообщает об ошибках пользователю - а затем передает преобразованные значения непосредственно в качестве параметров. Таким образом, вы знаете, что отправляете в БД действительное и правильное.


BASSIES

Привет,

Ввод текстового поля составляет, например, 14 025

Это десятичное число с 3 за запятой

Что я упускаю из виду

OriginalGriff

Что БД, вероятно, предположит, что это 14025?

Используйте десятичную дробь.Попробуйте преобразовать его, если это необходимо, сообщив ему, какой формат использовал пользователь (по умолчанию для западных компьютеров 14.025, а не 14.025, поэтому вам может потребоваться указать культуру для правильного преобразования).

https://docs.microsoft.com/en-us/dotnet/api/system.decimal.tryparse?view=netframework-4.7.2

BASSIES

Привет ,

Найдя что-то после вашего ответа , я записываю это в базу данных как десятичное число с запятой

Получите значение из базы данных, и оно будет с запятой . Хорошо, что именно так я хочу видеть его в текстовом поле.

Когда я обновляю, я должен использовать точку ?

Не знаю почему, но я работаю.

Никогда не нужно делать это с точкой , может быть, я сейчас использую версию 2017 года ?

Спасибо.

Patrice T

Привет ОГ,
Прочтите комментарии, которые я получил от ОП, они тоже для вас.

OriginalGriff

Спасибо! Приятно получить хоть немного благодарности, время от времени. :)