Reden Rodriguez Ответов: 2

Как сделать двойной выбор в C# с помощью хранимой процедуры


Привет всем, я пытаюсь поставить 2 select в магазине proc, а затем вызвать его в c#, чтобы уменьшить мой код

Вот мой магазин proc
ELSE IF(@Event = 'getOperatorInfo')
				BEGIN
					SELECT operatorCode,operatorClient,operatorName,Expiration
					FROM codecoOperatorInfo
					WHERE operatorCode = @operatorCode AND operatorClient = @operatorClient

					SELECT operatorRecipients
					FROM codecoOperatorsRecipients
					WHERE operatorCode = @operatorCode AND operatorClient = @operatorClient
				END


а вот и мой c# код

public List<operatorSettingsDO> getOperatorInfo(string Code, string Client)
        {
            var oOperatorSettingsDO = new List<operatorSettingsDO>();
            using (SqlConnection oConnection = new SqlConnection(sqlConnection))
            {
                using (SqlCommand oCommand = new SqlCommand("spCodeco", oConnection))
                {
                    oCommand.Connection = oConnection;
                    oCommand.CommandType = CommandType.StoredProcedure;
                    oCommand.Parameters.AddWithValue("@Form", "operatorSettings");
                    oCommand.Parameters.AddWithValue("@Event", "getOperatorInfo");
                    oCommand.Parameters.AddWithValue("@operatorCode", Code);
                    oCommand.Parameters.AddWithValue("@operatorClient", Client);
                    SqlDataReader oReader = null;
                    try
                    {
                        oConnection.Open();
                        oReader = oCommand.ExecuteReader();
                        while (oReader.Read())
                        {
                            operatorSettingsDO opSettingsDO = new operatorSettingsDO();
                            opSettingsDO.operatorCode = oReader["operatorCode"].ToString();
                            opSettingsDO.operatorClient = oReader["operatorClient"].ToString();
                            opSettingsDO.operatorName = oReader["operatorName"].ToString();
                            opSettingsDO.Expiration = (DateTime)oReader["Expiration"];


                            opSettingsDO.Recipients = oReader["operatorRecipients"].ToString();
                            oOperatorSettingsDO.Add(opSettingsDO);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
            return oOperatorSettingsDO;
        }


это говорит о системе.Класса indexoutofrangeexception "operatorRecipients"

Что я уже пробовал:

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

F-ES Sitecore

Ваш код возвращает два выбора результата, поэтому ваш ".Read" проходит через первый результат строка за строкой, а operatorRecipients в нем нет, поэтому вы не можете его прочитать. Как только вы завершите первый набор результатов, вам нужно будет перейти к следующему набору результатов и обработать его, и ваши operatorRecipients будут доступны там.

Richard Deeming

catch (Exception ex)
{
    throw ex;
}

Не делай этого. Вы только что отбросили трассировку стека исключения, что значительно затрудняет поиск источника ошибки.

Если вы действительно хотите повторно создать исключение, используйте throw; вместо throw ex;
catch (Exception ex)
{
    throw;
}

Но в этом случае, поскольку вы ничего не делаете с исключением, как только поймали его, вы можете также удалить его. try..catch блок полностью.

2 Ответов

Рейтинг:
7

MadMyche

Самый быстрый способ сделать это - использовать SQL Data Adapter; который, в свою очередь, создаст набор данных, содержащий один DataTable для каждого результирующего набора, возвращающегося из вашей процедуры

несколько результирующих наборов

Если DataAdapter сталкивается с несколькими результирующими наборами, он создает несколько таблиц в наборе данных. Таблицам присваивается инкрементное имя по умолчанию TableN, начинающееся с "Table" для Table0. Если имя таблицы передается в качестве аргумента методу Fill, то таблицам присваивается инкрементное имя по умолчанию TableNameN, начинающееся с "TableName" для TableName0.
Рекомендации:
Класс SqlDataAdapter (System.Data.SqlClient) | Microsoft Docs[^]
Заполнение набора данных из DataAdapter - ADO.NET | Microsoft Docs[^]


Рейтинг:
16

#realJSOP

var result = new DataSet();
        var dataAdapter = new SqlDataAdapter(command);
        dataAdapter.Fill(result);


В этот момент вы можете ссылаться на каждый результирующий набор в разных таблицах внутри набора данных...

result.Tables[0] и result.Tables[1]