Зацикливание через gridview для отправки в хранимую процедуру застревает в цикле

58
6

Я думаю, что я долго смотрел на это. У меня есть 2 gridviews с данными. Я хочу пройти через них и отправить каждый элемент в хранимую процедуру. Эта хранимая процедура проверяет дубликаты и отправляет назад 1, если они существуют, и 0, если они этого не делают. Хорошо, когда я делаю это для каждого цикла. Я застреваю. Я пробовал перемещать вещи без везения. Вот мой код:

public int IsExists() 
{
foreach (GridViewRow row in gvSerials.Rows)
{
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand("usp_InsertReceiptSerials", con))
{
cmd.CommandType = CommandType.StoredProcedure;
con.Open();
cmd.Parameters.Add("@ITEMNMBR", SqlDbType.Char).Value = OpenDescription.SelectedRow.Cells[5].Text.Trim();
cmd.Parameters.Add("@RecLineID", SqlDbType.Int).Value = int.Parse(OpenDescription.SelectedRow.Cells[1].Text.Trim());
cmd.Parameters.Add("@RCPTLNNM", SqlDbType.Int).Value = int.Parse(OpenDescription.SelectedRow.Cells[8].Text.Trim());
cmd.Parameters.Add("@POPRCTNM", SqlDbType.Char).Value = OpenDescription.SelectedRow.Cells[4].Text.Trim();
cmd.Parameters.Add("@SERLTNUM", SqlDbType.Char).Value = row.Cells[0].Text.Trim();
SqlParameter parm = new SqlParameter("@IsExists", SqlDbType.Int);
parm.Direction = ParameterDirection.Output;
cmd.Parameters.Add(parm);

cmd.ExecuteNonQuery();
con.Close();
}
}
}

return IsExists();
if (IsExists() == 1) {
MessageBox.Show("Serials Already Exists!!");
Response.Redirect("Index.aspx"); }
else if (IsExists() == 0) {
MessageBox.Show("Serial Numbers have been updated.", "Important Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
Response.Redirect("Index.aspx"); }
}

Здесь хранится proc:

 ALTER PROCEDURE [dbo].[usp_InsertReceiptSerials]
@POPRCTNM CHAR(17), @ITEMNMBR CHAR(31), @SERLTNUM CHAR(21), @RecLineID INT, @RCPTLNNM INT, @IsExists INT OUTPUT

AS
BEGIN
SET NOCOUNT ON;
DECLARE @RecCount INT
-- DECLARE @IsExists INT

IF EXISTS (SELECT * FROM dbo.vwSerialNumbers WHERE SERLNMBR = Right(@SERLTNUM,20) AND ITEMNMBR = @ITEMNMBR)
BEGIN
SET @IsExists = 1
END
ELSE
BEGIN
INSERT INTO dbo.usr_ReceiptSerials(POPRCTNM, ITEMNMBR, SERLTNUM, FullSerialNumber, EntryDate, RecLineID, RCPTLNNM)
VALUES (@POPRCTNM, @ITEMNMBR, Right(@SERLTNUM,20), @SERLTNUM, GetDate(), @RecLineID, @RCPTLNNM)
SET @RecCount = (SELECT COUNT(*) FROM dbo.usr_ReceiptSerials WHERE RecLineID = @RecLineID)
UPDATE dbo.usr_ReceiptLine SET QTYSHPPD = @RecCount
WHERE RecLineID = @RecLineID
SET @IsExists = 0
END
END

спросил(а) 2015-09-14T20:05:00+03:00 5 лет, 1 месяц назад
1
Решение
57

Я вижу проблему с простой рекурсией, которая вызывает stackoverflow.

=> return IsExists();

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

Кроме того, скорее, проверка if (IsExists() == 1)

использовать:

int result = cmd.ExecuteNonQuery(); Затем выполните оценку по результату:

   if (result == 1) {
MessageBox.Show("Serials Already Exists!!");
Response.Redirect("Index.aspx"); }
else if (result == 0) {
MessageBox.Show("Serial Numbers have been updated.", "Important Message", MessageBoxButtons.OK, MessageBoxIcon.Information);
Response.Redirect("Index.aspx"); }

Для ошибки построения вы должны вернуть целочисленное значение, которое ожидает метод. Например, это может быть result.

Обновить:

В вашем случае кажется, что вы хотите прочитать значение параметра Output. Чтобы прочитать значение выходного параметра из объекта Command, см. Этот ответ. Тогда переменная result будет назначаться параметром Output который вы будете читать из SqlParameter после извлечения команды.

ответил(а) 2015-09-14T20:16:00+03:00 5 лет, 1 месяц назад
41

Основываясь на другом ответе:

public int IsExists() 
{
int returnInt =0;
foreach (GridViewRow row in gvSerials.Rows)
{
using (SqlConnection con = new SqlConnection(strConnString))
{
using (SqlCommand cmd = new SqlCommand("usp_InsertReceiptSerials", con))
{
// /.../
if whatever your testing is true:
returnInt = 1;
or
return returnInt;

or
return 1;
or wait until the end of the method if you want to add more stuff.
}
}
}
// Do any more stuff here.

return returnInt();
// Nothing beyond here is executed.

}

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

ответил(а) 2015-09-14T20:25:00+03:00 5 лет, 1 месяц назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема