Я пытаюсь использовать этот код, чтобы получить сумму суммы из базы данных:

MySqlCommand cmdsumpayment = new MySqlCommand("SELECT sum(amount) as'total' from payments where unit_id = " + UNITID + " AND deleted_at IS NULL", conn);
                        MySqlDataReader rdr2 = cmdsumpayment.ExecuteReader();
                        if (rdr2.HasRows) {
                            while (rdr2.Read())
                        {
                            TOTALPAYMENTS = rdr2.GetInt32("total");
                        }
                        }
                        else
                            MessageBox.Show("nothing found");

Это работает, и я могу получить сумму (сумму) из таблицы платежей, но моя проблема в том, что если я ищу что-то, что не имеет платежей, я получаю эту ошибку:

System.InvalidCastException: 'Specified cast is not valid.

Например, если идентификатор единицы = 1 и у нее есть платежи, я могу получить результат в ОБЩЕМ ПЛАТЕЖЕ, но если у него нет платежей, я получаю ошибки, и приложение аварийно завершается. может кто-нибудь помочь мне справиться с пустым поиском без сбоев? Я тоже пробую if (rdr2.HasRows), но это не работает, я не знаю почему.

0
Arsalan Ahmadi 27 Ноя 2021 в 10:51

1 ответ

Лучший ответ

Я на 100% уверен, что у вас есть amount null в таблице, а затем вы получаете приведение типа при преобразовании в целое число. В опубликованном вами коде вы не получите исключение приведения типа, если в таблице нет строк для данного условия. Таким образом, вы можете установить точку останова и отладить или добавить журналы. Вы также можете попробовать запустить запрос прямо в базу данных, чтобы узнать, возвращает ли он записи или нет.

Вы можете изменить запрос, если сумма равна нулю.

SELECT sum(isnull(amount, 0)) as'total' from payments where unit_id = " + UNITID + " AND deleted_at IS NULL

И я бы рекомендовал использовать параметризованный запрос, чтобы избежать внедрения sql.

Изменить : у меня есть основная причина вашей проблемы. SqlDataReader.GetInt32 ожидает целочисленное значение, а вы передаете строковое значение. Поэтому вам нужно передать 0 вместо “total”. Как упоминалось в документации, вы должны вызвать IsDBNull для проверки нулевых значений перед вызовом этого метода.

2
vivek nuna 27 Ноя 2021 в 11:54
Здравствуйте, я пробовал ваш код, но получаю эту ошибку: MySqlConnector.MySqlException: 'Incorrect parameter count in the call to native function 'isnull''. Кроме того, я просто снял флажок «Разрешить нулевое значение для столбца суммы», поэтому теперь мы уверены, что в нем нет нулевого значения, проблема в том, что он выдаст ошибку, когда мы ищем то, чего не существует, я имею в виду, что UNITID =1 существует но UNITID = 10 там не существует, вот тогда я и получил ошибку. Извините за мой плохой английский. проверьте это на картинке, я думаю, вы меня поймете:
 – 
Arsalan Ahmadi
27 Ноя 2021 в 11:18
 – 
Arsalan Ahmadi
27 Ноя 2021 в 11:19
Какая строка вызывает исключение @ArsalanAhmadi?
 – 
vivek nuna
27 Ноя 2021 в 11:34
Когда я использую sum(amount) as 'total', эта строка выдает ошибку: TOTALPAYMENTS = rdr2.GetInt32("total");, а ошибка: System.InvalidCastException: 'Specified cast is not valid., но когда я использую запрос, который вы мне отправляете, эта строка дает мне ошибку: MySqlDataReader rdr2 = cmdsumpayment.ExecuteReader(); и ошибка: MySqlConnector.MySqlException: 'Incorrect parameter count in the call to native function 'isnull''
 – 
Arsalan Ahmadi
27 Ноя 2021 в 11:48
1
Спасибо за помощь, я решил проблему, добавив if (!rdr2.IsDBNull(rdr2.GetOrdinal("total"))) перед TOTALPAYMENTS = rdr2.GetInt32("total");, как вы меня учите. а что касается SQL-инъекций, я немного новичок, поэтому я пока пытаюсь изучить запрос и то, как с ним работать, а затем я постараюсь узнать, как избежать инъекций.
 – 
Arsalan Ahmadi
27 Ноя 2021 в 12:03