Что в этом не так?

private int DBUpdate () {

DAL dal = new DAL();
string upd = "UPDATE [RPform] SET [ProjectName] = '@pname', [ProjectCode] = '@pcode', [Country] = @cnt, ";
upd += "[StartDate] = '@startdate', [FinishDate] = '@finishdate', [TotalParticipants] = @totpart, [ArrivalDate] = '@arrivedate', ";
upd += "[AirportTransfer] = @airtran, [AirportDate] = '@airdate', [AirportHours] = @airhour, [AirportMinutes] = @airmin, ";
upd += "[Problems] = '@problems', [FirstDayActivities] = '@fdayact' ";
upd += "WHERE [UserID]=@usid";

    OleDbParameter[] parm = new OleDbParameter[] { 
    new OleDbParameter("@pname",projname.Text),
    new OleDbParameter("@pcode",projcode.Text),
    new OleDbParameter("@cnt",countries.SelectedIndex),
    new OleDbParameter("@startdate",datestart.Text),
    new OleDbParameter("@finishdate",datefinish.Text),
    new OleDbParameter("@totpart",totalparticipants.Text),
    new OleDbParameter("@arrivedate",datearrival.Text),
    new OleDbParameter("@airtran",RadioButtonList1.SelectedValue),
    new OleDbParameter("@airdate",dateairport.Text),
    new OleDbParameter("@airhour",airporthours.SelectedIndex),
    new OleDbParameter("@airmin",airportminutes.SelectedIndex),
    new OleDbParameter("@problems",problems.Value),
    new OleDbParameter("@fdayact",firstday.Value),
    new OleDbParameter("@usid",user.ID)
    };
 return (dal.UpdateRow(upd,false,parm));
}

/// Не вызывает никаких исключений, но возвращает 0 затронутых строк. Когда тот же запрос выполняется из MS Access, он работает нормально. Следовательно, я полагаю, что проблема связана с обработкой параметров... но что? Спасибо


Серхио: это нормально, для явной установки OleDbTypes?

///whatever ...
        new OleDbParameter("@problems",problems.Value),
        new OleDbParameter("@fdayact",firstday.Value),
        new OleDbParameter("@usid",user.ID)
        };
//then telling each one what they will be ... 
        parm[0].OleDbType = OleDbType.VarWChar;
        parm[1].OleDbType = OleDbType.VarWChar;

///
     return (dal.UpdateRow(upd,false,parm));

7 ответов

Проверьте, правильно ли установлено значение user.ID.

В вашей командной строке upd вы заключаете параметры в кавычки, например так:

[StartDate] = '@startdate'

Удалите эти цитаты во всех ваших параметрах.

Извините, Эмре, я упустил из виду поставщика OleDb. Ваш синтаксис команды SQL правильный, если он предназначен для поставщика SQL.

Итак, ваша команда должна выглядеть так:

string upd = "UPDATE [RPform] SET [ProjectName] = ?, [ProjectCode] = ?, [Country] = ?, ";
upd += "[StartDate] = ?, [FinishDate] = ?, [TotalParticipants] = ?, [ArrivalDate] = ?, ";
upd += "[AirportTransfer] = ?, [AirportDate] = ?, [AirportHours] = ?, [AirportMinutes] = ?, ";
upd += "[Problems] = ?, [FirstDayActivities] = ? ";
upd += "WHERE [UserID]=?";

Затем вы должны добавить свои параметры OleDb точно так же, как вы уже это сделали, но вы должны быть осторожны, чтобы добавить их в том же порядке, в котором они появляются в вашей SQL-команде.

Еще одна вещь, но это не имеет отношения к вашей проблеме: вам не следует объединять строки, потому что эта операция не очень хороша с точки зрения производительности.

Вместо этого, чтобы выложить свою команду SQL, попробуйте это:

StringBuilder upd = new StringBuilder();
upd.Append("UPDATE [RPform] SET [ProjectName] = ?, [ProjectCode] = ?, [Country] = ?, ");
upd.Append("[StartDate] = ?, [FinishDate] = ?, [TotalParticipants] = ?, [ArrivalDate] = ?, ");
upd.Append("[AirportTransfer] = ?, [AirportDate] = ?, [AirportHours] = ?, [AirportMinutes] = ?, ");
upd.Append("[Problems] = ?, [FirstDayActivities] = ? ");
upd.Append("WHERE [UserID]=?");

Затем, чтобы получить командную строку, вам просто нужно:

upd.ToString();

Надеюсь, что это поможет вам.

Просто чтобы прокомментировать, что вместо конкатенации, он более читабелен (и его легче копировать / вставлять), если вы используете многострочный строковый литерал. Также не следует заключать имена параметров в одинарные кавычки, даже для строковых параметров (используйте одинарные кавычки только для литералов). Таким образом, ваш оригинальный SQL может выглядеть примерно так:

string upd = @"
UPDATE [RPform] SET [ProjectName] = @pname, [ProjectCode] = @pcode, [Country] = @cnt, 
[StartDate] = @startdate, [FinishDate] = @finishdate, [TotalParticipants] = @totpart, [ArrivalDate] = @arrivedate, 
[AirportTransfer] = @airtran, [AirportDate] = @airdate, [AirportHours] = @airhour, [AirportMinutes] = @airmin, 
[Problems] = @problems, [FirstDayActivities] = @fdayact 
WHERE [UserID]=@usid
";

Как уже отмечали другие, OleDb не использует именованные параметры, поэтому вам следует использовать следующее, гарантируя, что вы добавляете параметры в OleDbCommand в том же порядке, в котором они появляются в операторе SQL:

string upd = @"
UPDATE [RPform] SET [ProjectName] = ?, [ProjectCode] = ?, [Country] = ?, 
[StartDate] = ?, [FinishDate] = ?, [TotalParticipants] = ?, [ArrivalDate] = ?, 
[AirportTransfer] = ?, [AirportDate] = ?, [AirportHours] = ?, [AirportMinutes] = ?, 
[Problems] = ?, [FirstDayActivities] = ? 
WHERE [UserID]=?
";

Не используйте StringBuilder в этом случае. Используйте дословные строки (@) с хорошо отформатированным кодом SQL:

var updateStatement = @"
    UPDATE [RPform]
    SET     [ProjectName]        = @pname     ,
            [ProjectCode]        = @pcode     ,
            [Country]            = @cnt       ,
            [StartDate]          = @startdate ,
            [FinishDate]         = @finishdate,
            [TotalParticipants]  = @totpart   ,
            [ArrivalDate]        = @arrivedate,
            [AirportTransfer]    = @airtran   ,
            [AirportDate]        = @airdate   ,
            [AirportHours]       = @airhour   ,
            [AirportMinutes]     = @airmin    ,
            [Problems]           = @problems  ,
            [FirstDayActivities] = @fdayact
    WHERE   [UserID]             =@usid";

Но я должен отметить, что += не будет оптимизирован! Простой + будет выполнен во время компиляции. Например

string s = "A" + "B" + C"; 

приведет к "ABC" без перфом хит Однако

string s = "A" + variable + C";

будет не оптимизирован.

Если вы устанавливаете тип параметра в каждом новом OleDbParameter, вам не нужно помещать одинарные кавычки в SQL, что делает инструкцию менее склонной к ошибкам ввода.

Кстати, вы, вероятно, захотите использовать StringBuilder вместо строки для создания upd. Каждый раз, когда вы используете +=, вы выбрасываете старую строку, создавая новую.

Пытаться

StringBuilder upd = new StringBuilder();
upd.Append("UPDATE [RPform] SET [ProjectName] = '@pname', [ProjectCode] = '@pcode', [Country] = @cnt, ");
upd.Append("[StartDate] = '@startdate', [FinishDate] = '@finishdate', [TotalParticipants] = @totpart, [ArrivalDate] = '@arrivedate', ");
upd.Append("[AirportTransfer] = @airtran, [AirportDate] = '@airdate', [AirportHours] = @airhour, [AirportMinutes] = @airmin, ");
upd.Append("[Problems] = '@problems', [FirstDayActivities] = '@fdayact' ");
upd.Append("WHERE [UserID]=@usid");

И использовать это, просто

upd.ToString();

Aight! Я решил это слушая Deltron 3030 .. это всегда работает:)

Этот объект OleDbParameter устанавливает свой oledbtype внутренне, в соответствии с типом, который я передал (как объект в ctor) .. поэтому я передал целое число, полученное из TextBox (проверенная на стороне клиента, но все еще текстовая, поэтому он падает).. также bool one было radiobutton.Value... который отправляет True, но все еще текст, поэтому он принимает в виде строки и заключает его в одинарные кавычки... Но я не вижу, какие имена давать этим параметрам, поскольку они безымянные...

Извините, я ненавижу читать длинные статьи, вместо этого я использую одно из великих достоинств программиста - лень.. Поэтому я спрашиваю здесь:)

Спасибо всем за ваше время и усилия. Желаю вам, ребята, всех успехов.

Другие вопросы по тегам