ошибка преобразования varchar в число в строке обновления

У меня проблема с моим кодом обновления, ошибка преобразования varchar в числовое создает исключение. Он имеет дело с двумя таблицами.

table1(WEB_ADDRESS) состоит из адресной информации, которая отправляется в службу API геокодирования.

|PKID | ADDRESS_ID | ADDRESS_1 | CITY | etc...

table2(WEB_ADDRESS_GEO) состоит из широты и долготы, полученных от службы API.

ADDRESS_ID | Lat | Lng

Мне нужно обновить строки данных в таблице 2 с помощью lats и lngs, чтобы они соответствовали данным адреса в таблице 1.

вот код здесь

  using (SqlConnection myConnection = new SqlConnection(context))
  {
      myConnection.Open();
      string strQueryUpdate = "UPDATE WEB_ADDRESS_GEO SET Lat = '" + strLat + "', Lng = '" + strLng + "'" + "WHERE ADDRESS_ID=" + row.ADDRESS_ID;
      SqlCommand myCommandUpdate = new SqlCommand(strQueryUpdate, myConnection);
      myCommandUpdate.ExecuteNonQuery();

столбец ADDRESS_ID имеет тип VarChar, Lat и Lng имеют десятичный тип.

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


person RyeNyeTheComputerScienceGuy    schedule 11.12.2014    source источник
comment
Вы почувствуете гнев богов SQL-инъекций, выполнив эту конкатенацию строк вместо использования подготовленных операторов/параметров...   -  person Patryk Ćwiek    schedule 11.12.2014
comment
Примечание. SQL-инъекция — не единственная причина использования параметризованных команд. Например, параметры имеют явные типы, поэтому вы можете избежать проблем с типами, таких как у вас здесь (или, по крайней мере, их легче увидеть).   -  person Chris    schedule 11.12.2014


Ответы (1)


Если ADDRESS_ID равно VarChar, вам нужно использовать одинарные кавычки, например;

"WHERE ADDRESS_ID= '" + row.ADDRESS_ID + "'"

Если Lat и Lng равны decimal, вам не нужно использовать с ними одинарные кавычки.

SET Lat = " + strLat + ", Lng = " + strLng

Лучше использовать параметризованные запросы. . Такого рода конкатенации строк открыты для атак SQL Injection.

using(SqlConnection myConnection = new SqlConnection(context))
using(SqlCommand myCommandUpdate = conn.CreateCommand())
{
   myCommandUpdate.CommandText = @"UPDATE WEB_ADDRESS_GEO SET Lat = @lat, Lng = @lng 
                                  WHERE ADDRESS_ID = @address";
   myCommandUpdate.Parameters.Add(@lat, SqlDbType.Decimal).Value = strLat;
   myCommandUpdate.Parameters.Add(@lng, SqlDbType.Decimal).Value = strLng;
   myCommandUpdate.Parameters.Add(@address, SqlDbType.VarChar).Value = row.ADDRESS_ID;
   myConnection.Open();
   myCommandUpdate.ExecuteNonQuery();
}

Но судя по вашим именам переменных, strLat и strLng действительно звучат как некоторые символьные значения, а не числовые значения. Это противоположно вашему значению row.ADDRESS_ID. В основном переменная содержит ID в качестве имени, используемого в числовых значениях, а не в символах.

person Soner Gönül    schedule 11.12.2014
comment
Даже если вы не беспокоитесь о внедрении SQL (потому что вы на 100% доверяете источнику), параметризованные запросы лучше справляются с типами, потому что вам не нужно беспокоиться о том, правильно ли вы цитируете и тому подобное. - person Chris; 11.12.2014
comment
NB. Я думаю, вам следует удалить комментарии ADDRESS_ID. Идентификаторы обычно являются числовыми, и нет причин подозревать, что в данном случае это не так, и это скрывает реальную проблему, о которой вы упоминаете далее. - person Chris; 11.12.2014
comment
Похоже, лучший ответ на этот вопрос — просто использовать параметризованные запросы. Так что я сделаю это. - person RyeNyeTheComputerScienceGuy; 11.12.2014
comment
@RyeNyeTheWebSiteGuy В чем именно ошибка? Не могли бы вы быть более конкретным? - person Soner Gönül; 11.12.2014
comment
@ Крис Точно. Их имена действительно звучат так же противоположно, как и их типы, о которых я упоминал. - person Soner Gönül; 11.12.2014
comment
Идентификатор выглядит как 70-00001223. - person RyeNyeTheComputerScienceGuy; 11.12.2014
comment
@RyeNyeTheWebSiteGuy Мне это не кажется числовым значением. Использование типа VarChar будет хорошим выбором. - person Soner Gönül; 11.12.2014