el_tot93 Ответов: 3

Ошибка преобразования в тип varchar значение "12345" в тип данных int


я пытаюсь использовать этот код для удаления записей из моей базы данных, но у меня есть эта ошибка.
мой тип столбца для id-это (int), в чем проблема

List<string> selectedIds = new List<string>();
            foreach (DataGridViewRow item in advancedDataGridView1.Rows)
            {
                if (bool.Parse(item.Cells[0].Value.ToString()))
                {
                    selectedIds.Add("'" + item.Cells[1].Value.ToString() + "'");
                    // collecting all ids
                }
            }
            String sql = "delete from tabl where id in(@idsToDelete)";
            using (SqlConnection cn = new SqlConnection("Data Source=DESKTOP-J7D5POF;Initial Catalog=ilswork;Persist Security Info=True;User ID=***;Password=***"))
            {
                cn.Open();
                using (SqlCommand cmd = new SqlCommand(sql, cn))
                {
                    cmd.Parameters.Add("@idsToDelete", SqlDbType.varchar).Value = string.Join(",", selectedIds);
                    cmd.ExecuteNonQuery();
                }
            }


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

using (SqlCommand cmd = new SqlCommand(sql, cn))
                {
                    cmd.Parameters.Add("@idsToDelete", SqlDbType.Int).Value = string.Join(",", selectedIds);
                    cmd.ExecuteNonQuery();
                }


я получаю эту ошибку (не удалось преобразовать значение параметра из строки в Int32)

Bryian Tan

Похоже, что код передается в string вместо int

el_tot93

так что же мне делать

3 Ответов

Рейтинг:
22

Wendelius

Возможно, самым простым способом было бы объединить отдельный параметр для каждого значения.

Рассмотрим следующий пример

String sql;
int parameterCounter;
SqlParameter parameter;

sql = "delete from tabl where id in (";
parameterCounter = 0;

using (SqlConnection cn = new SqlConnection("....")) {
   using (SqlCommand cmd = new SqlCommand(sql, cn)) {
      foreach (DataGridViewRow item in advancedDataGridView1.Rows) {
         if (bool.Parse(item.Cells[0].Value.ToString())) {
            parameterCounter++;
            parameter = new SqlParameter();
            parameter.ParameterName = "@par" + parameterCounter.ToString();
            parameter.DbType = System.Data.DbType.Int32;
            parameter.Value = item.Cells[1].Value;
            cmd.Parameters.Add(parameter);
            sql = sql + $"{parameter.ParameterName},";
            // collecting all ids
         }
      }
      sql = sql.TrimEnd(',');
      sql = sql + ")";

      cmd.CommandText = sql;
      cmd.Connection = cn;
      cn.Open();
      cmd.ExecuteNonQuery();
   }
}


el_tot93

это дало мне ошибку System.Data.SqlClient.SqlException: 'неправильный синтаксис рядом ')'.'

Wendelius

Если вы используете отладчик, то как выглядит строка sql?

Wendelius

На самом деле я заметил проблему, в триместре отсутствовало задание. Теперь этот пример исправлен:

sql = sql.TrimEnd(',');

el_tot93

теперь отладчик (параметризованный запрос '(@par1 int)delete from tabl where id in (@par1)' ожидает параметр '@par1', который не был указан.')

Wendelius

К сожалению, мой плохой. Присвоение значения отсутствовало. У меня нет компилятора под рукой, поэтому немного сложно использовать только блокнот...

В этом примере была добавлена следующая строка

параметр.Значение = предмет.Ячейки[1].Значение;

Если у вас возникнут дополнительные проблемы с моим примером кода, дайте мне знать.

el_tot93

Спасибо Вам большое я хорошо работаю со мной

el_tot93

нужно ли было прерывать связь ???
спицы.Открыть();
УМК.Метод executenonquery();
спицы.рядом();

Wendelius

Рад слышать, что это работает!

Поскольку SqlConnection находится в блоке using, вам не нужно закрывать соединение. Взгляните на это Объект sqlconnection.Метод Закрытия (System.Data.SqlClient) | Microsoft Docs[^]

el_tot93

спасибо wandelius

Wendelius

Пожалуйста :)

Рейтинг:
13

OriginalGriff

Почему вы пытаетесь передать коллекцию "целочисленных" значений (когда на самом деле они являются целыми числами в виде строк), сформированную в виде списка значений, разделенных запятыми, как одно целое число?

cmd.Parameters.Add("@idsToDelete", SqlDbType.Int).Value = string.Join(",", selectedIds);

Конечно, это не сработает! SQL будет получать строку, как это :
'1,2,3,4'
И попробуйте преобразовать это в одно целое значение, потерпите неудачу и выдадите ошибку.

Затем, когда вы это исправите, возникает другая проблема: это не будет работать.
Решение проблемы смотрите здесь: Использование разделенных запятыми строк параметров значений в предложениях SQL IN[^]


el_tot93

Так что же такое правильный путь? Я ничего не понял из Линка ..

Maciej Los

5ed!

Рейтинг:
0

Maciej Los

Если я вас хорошо понимаю, вы хотите передать несколько параметров в sql-команду в виде одного параметра (списка идентификаторов).

List<string> selectedIds = new List<string>();
//...
selectedIds.Add("'" + item.Cells[1].Value.ToString() + "'"); 
//...
String sql = "delete from tabl where id in(@idsToDelete)";
//...
cmd.Parameters.Add("@idsToDelete", SqlDbType.varchar).Value = string.Join(",", selectedIds);

Как упоминал OriginalGriff, вы пытаетесь передать строковое значение ('1,2,3,4') в команду sql вместо их исходных значений(массив [1,2,3,4]). Итак, ваша команда получает один параметр varchar вместо массива числовых значений! Это главная причина вашей ошибки. Таким образом, вы можете решить свою проблему с помощью:
1) передача каждого отдельного значения в команду и выполнение команды в цикле, но это может быть причиной низкой производительности. Это может выглядеть так DDoS-атака[^]!
или
2) передача массива значений в команду.
Рекомендуемый способ заключается в использовании Возвращающие Табличное Значение Параметры | Майкрософт Документы[^]. Перейдите по ссылке. Там вы найдете информацию о том, как этого добиться!