Оператор обновления Обновляет 0 строк через приложение C # Winform? - PullRequest
1 голос
/ 29 мая 2010

Прежде всего, пожалуйста, помогите мне! Я не могу это больше терпеть. Я не мог найти, где находится ошибка. Вот моя проблема:

Я пытаюсь обновить строку через приложение c # winform. Запрос на обновление, сгенерированный из приложения, отформатирован правильно. Я проверил его в среде сервера SQL, он работал хорошо. Когда я запускаю его из приложения, я получаю 0 обновленных строк.

Вот фрагмент кода, который генерирует оператор обновления с использованием отражения - не пытайтесь выяснить это. Продолжайте чтение после части кода:

        public void Update(int cusID)
        {
            SqlCommand objSqlCommand = new SqlCommand();
            Customer cust = new Customer();

            string SQL = null;

            try
            {
                if ((cusID != 0))
                {
                        foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
                        {
                            if (!(PropertyItem.Name.ToString() == cust.PKName))
                            {
                                if (PropertyItem.Name.ToString() != "TableName")
                                {
                                    if (SQL == null)
                                    {
                                        SQL = PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString();
                                    }
                                    else
                                    {
                                        SQL = SQL + ", " + PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString();
                                    }
                                 }
                                 else
                                 {
                                    break;
                                 }
                            }
                       }

                        objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + "'" + "@phNum" + "'";

                        foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
                        {
                            if (!(PropertyItem.Name.ToString() == cust.PKName))
                            {
                                if (PropertyItem.Name.ToString() != "TableName")
                                {
                                    objSqlCommand.Parameters.AddWithValue("@" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null));
                                }
                                else
                                {
                                    break;
                                }

                            }
                        }

                        objSqlCommand.Parameters.AddWithValue("@cusID", cusID);
                        objSqlCommand.Parameters.AddWithValue("@phNum", this.PhoneNumber);
                        DAL.ExecuteSQL(objSqlCommand);
                }
                else
                {
                    //AppEventLog.AddWarning("Primary Key is not provided for Update.")
                }

            }
            catch (Exception ex)
            {
                //AppEventLog.AddError(ex.Message.ToString)
            }
        }

Эта часть ниже:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + "'" + "@phNum" + "'";

генерирует dml:

UPDATE CustomerPhone SET PhoneTypeID = @PhoneTypeID, PhoneNumber = @PhoneNumber WHERE CustomerID = @cusID AND PhoneNumber = '@phNum'

@ PhoneTypeID и @PhoneNumber получены из двух свойств. Мы присвоили значение этим свойствам на уровне представления из текстового поля ввода пользователя. Часть ниже, где извлекаются значения:

objSqlCommand.Parameters.AddWithValue("@" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null));

Код ниже заполняет значения WHERE:

                    objSqlCommand.Parameters.AddWithValue("@cusID", cusID);
                    objSqlCommand.Parameters.AddWithValue("@phNum", this.PhoneNumber);

Окончательный код должен выглядеть так:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = 999444
WHERE CustomerID = 500 AND PhoneNumber = '911';

Идентификатор типа телефона: 7 - пользовательское значение, которое берется из текстового поля. Номер телефона 999444 - пользовательское значение, которое берется из текстового поля

Указанный выше последний оператор обновления работает в среде sql, но при запуске через приложение выполнение без запроса выполняется нормально и обновляется 0 строк! Интересно почему?

Ответы [ 2 ]

3 голосов
/ 29 мая 2010

Это проблема:

AND PhoneNumber = '@phNum'

Это ищет номер телефона, который в точности соответствует тексту '@phNum' - это , а не с использованием параметра, называемого phNum. Вы хотите

AND PhoneNumber = @phNum

Вы также разбиваете свои строковые литералы без видимой причины. Это утверждение:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + 
    " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + 
    "'" + "@phNum" + "'";

будет более легко читаемым как:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL +
    " WHERE " cust.PKName + " = @cusID AND PhoneNumber = '@phNum'";

Очевидно, что вы хотите выбросить из него одинарные кавычки, чтобы сделать это просто:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL +
    " WHERE " cust.PKName + " = @cusID AND PhoneNumber = @phNum";

Небольшой рефакторинг тоже не помешает. Этот цикл:

foreach (PropertyInfo PropertyItem in this.GetType().GetProperties())
{
    if (!(PropertyItem.Name.ToString() == cust.PKName))
    {
        if (PropertyItem.Name.ToString() != "TableName")
        {
            if (SQL == null)
            {
                SQL = PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString();
            }
            else
            {
                SQL = SQL + ", " + PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString();
            }
         }
         else
         {
            break;
         }
    }

}

было бы проще и читабельнее, как это:

StringBuilder sqlBuilder = new StringBuilder();
foreach (PropertyInfo property in this.GetType().GetProperties())
{
    string name = property.Name;
    // I believe you had a bug before - the properties being updated
    // would depend on the ordering of the properties - if it
    // ran into "TableName" first, it would exit early!
    // I *suspect* this is what you want
    if (name != cust.PKName && name != "TableName")
    {
        sqlBuilder.AppendFormat("{0} = @{0}, ", name);
    }
}
// Remove the trailing ", "
if (sqlBuilder.Length > 0)
{
    sqlBuilder.Length -= 2;
}

Вы можете сделать что-то подобное и с последним циклом.

2 голосов
/ 29 мая 2010

Является ли PhoneNumber строкой или целым числом?

Я вижу, что вы SET говорите как целое число, но отмечаете WHERE как литерал. Может ли это быть проблемой?

Если это целое число, попробуйте:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = 999444
WHERE CustomerID = 500 AND PhoneNumber = 911;

Если это строка, попробуйте:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = '999444'
WHERE CustomerID = 500 AND PhoneNumber = '911';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...