Обработка ошибок в сохраненном операторе? - PullRequest
0 голосов
/ 12 августа 2010

Вот моя хранимая процедура обновления записей:

ALTER
PROCEDURE [dbo].[sp_UpdatetoShipped]
(
@Date datetime,
@SerialNumber
varchar(50),
@User
varchar(50),
@WorkWeek
varchar(50) 
)
AS
BEGIN

UPDATE dbo.FG_FILLIN SET Status='SHIPPED',DateModified=@Date,ModifiedBy=@User,WorkWeek=@WorkWeek where (Status='KITTED')and SerialNumber=@SerialNumber

END

Тогда это мой DAL:

public int UpdatetoShipped(FillinEntity fin) 
{
SqlConnection conn = new SqlConnection(connStr); 
conn.Open();
SqlCommand cmd = new SqlCommand("sp_UpdatetoShipped", conn); 
cmd.CommandType =CommandType.StoredProcedure; 
try
{
cmd.Parameters.Add("@SerialNumber", SqlDbType.VarChar,50).Value = fin.SerialNumber; 
cmd.Parameters.Add("@WorkWeek", SqlDbType.VarChar, 50).Value = fin.WorkWeek; 
cmd.Parameters.Add("@Date", SqlDbType.DateTime).Value = DateTime.Now.ToString(); 
cmd.Parameters.AddWithValue("@User", fin.ModifiedBy); 
return cmd.ExecuteNonQuery(); 
}
catch
{
throw; 
}
finally
{
cmd.Dispose();
conn.Close();
conn.Dispose();
}
}

Мой BLL:

public int UpdatetoShipped(FillinEntity fin) 
{
DAL pDAL = new DAL(); 
try
{
return pDAL.UpdatetoShipped(fin); 
}
catch
{
throw; 
}
finally
{
pDAL = null; 
}
}

И МОЙ UI:

string filepath2 = txtPath2.Text; 
Stream stream2 = new FileStream(filepath2, FileMode.Open, FileAccess.Read, FileShare.Read); 
ExcelMapper<FillinEntity> exceltoshipped = new ExcelMapper<FillinEntity>(); 
IExcelParser excelParser2 = new ExcelReaderExcelParser(stream2); 
IExcelRowMapper<FillinEntity> mapper2 = new ShippedRowMapper(); 
IEnumerable<FillinEntity> fillin2 = exceltoshipped.ListAll(excelParser2, mapper2);
int intResult = 0; 
BAL pBAL = new BAL();
try
{
foreach (FillinEntity fin in fillin2) 
{
fin.ModifiedBy = loggedUser;
intResult = pBAL.UpdatetoShipped(fin);
}
if (intResult > 0) 
MessageBox.Show("Record Updated Successfully."); 
else
MessageBox.Show("Record couldn't Updated Check Serial"); 
}
catch (Exception ee) 
{
MessageBox.Show(ee.Message.ToString()); 
}
finally
{
pBAL =null; 
}

Моя проблема в том, что всегда обновляется успешно. Но если я обновлю его снова как повторяющееся обновление, я хочу показать, что серийный номер уже обновлен.

Ответы [ 2 ]

1 голос
/ 12 августа 2010

Ключевое изменение, которое вам нужно сделать, это следующая строка SQL из вашей хранимой процедуры:

UPDATE dbo.FG_FILLIN 
SET   Status='SHIPPED',
      DateModified=@Date,
      ModifiedBy=@User,
      WorkWeek=@WorkWeek 
WHERE (Status='KITTED')
AND   SerialNumber=@SerialNumber

Вам необходимо вернуть значение, которое позволяет вам определить, уже произошло это ОБНОВЛЕНИЕ или нет, например:

DECLARE @iUpdateAlreadyComplete INT
SET @iUpdateAlreadyComplete = 0;
IF EXISTS 
 (
    SELECT 1 
    FROM   dbo.FG_FILLIN 
    WHERE  Status='SHIPPED' 
    AND    SerialNumber=@SerialNumber
  )
BEGIN
  SET @iUpdateAlreadyComplete = 1
END
ELSE
BEGIN
    UPDATE dbo.FG_FILLIN 
    SET   Status='SHIPPED',
          DateModified=@Date,
          ModifiedBy=@User,
          WorkWeek=@WorkWeek 
    WHERE (Status='KITTED')
    AND   SerialNumber=@SerialNumber 
END

SELECT @iUpdateAlreadyComplete AS Result

Затем вы можете изменить свой DAL с return cmd.ExecuteNonQuery(); на:

var result = Convert.ToInt32(cmd.ExecuteScalar());

return result;

Возвращаемое значение теперь будет 0 для записи, которая была обновлена, и 1 для записи, которая не нуждалась в обновлении, поскольку она уже была обработана.

Другие заметки

Есть несколько других вещей, которые вы должны рассмотреть, чтобы изменить:

  • sp_UpdatetoShipped - это имя bad для хранимой процедуры. Не используйте префикс sp_ .
  • Ваш DAL сознательно catch es и throw является исключением (по общему признанию "лучшим" способом), вам действительно нужно?
  • Вместо явного вызова Dipose() используйте вместо этого синтаксис using() {}, поскольку это гарантирует, что Dispose() вызывается даже в случае исключения.

using синтаксис:

using(SqlConnection conn = new SqlConnection(connStr))
{
    conn.Open();
    using (SqlCommand cmd = new SqlCommand("sp_UpdatetoShipped", conn))
    {
    }
}
0 голосов
/ 12 августа 2010

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

например

Dictoinary<string,string> updatedSerialNumbers = new Dictionary<string, string>();

foreach (FillinEntity fin in fillin2) 
{
fin.ModifiedBy = loggedUser;
if (updatedSerialNumbers.Contains(fin.SerialNumber) == false)
{ 
  intResult = pBAL.UpdatetoShipped(fin);
  updatedSerialNumbers.Add(fin.SerialNumber,fin.SerialNumber);
}

Что-то подобное должно решить вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...