Ограничение результатов из базы данных

В нашей службе С# мне нужно предоставить быстрое исправление сценария сбоя приложения.

Сбой службы при попытке запустить хранимую процедуру из-за огромного объема возвращаемых данных. Мы думаем ограничить набор результатов со стороны служб.

OracleCommand oraCommand = GetStoredProcedureCommand("SomeProc");
oraParam = new OracleParameter("param1", OracleDbType.Varchar2, 
 ParameterDirection.Output);
oraParam.Size = 32000;
oraCommand.Parameters.Add(oraParam);
oraParam = new OracleParameter("param2", OracleDbType.Varchar2, 
 ParameterDirection.Input);
oraParam.Value = strSelectedUser;
oraCommand.Parameters.Add(oraParam);

OracleDataAdapter oraDataAdapter = new OracleDataAdapter(oraCommand);
oraDataset = new DataSet();
oraDataAdapter.Fill(oraDataset);//I want to limit the number of records read to the servcie

База данных по-прежнему выполняет процесс полностью, что плохо, но у нас нет времени исправить это сейчас. Нам нужно ограничить данные, которые извлекаются на службу С#, и, следовательно, предотвращать сбои.

Как мы можем ограничить данные? Обратите внимание: если можно использовать набор данных, мы должны придерживаться этого в качестве набора данных, который он передавал на сервере. Но если нет другого способа, я могу реорганизовать код.

3 ответа

Опция 1:

Можете ли вы использовать SELECT TOP xxx в своей хранимой процедуре?

Oracle SELECT TOP 10 записей

Это вернет первое количество записей xxxx для запроса, позволяющее указать лимит.

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

Вариант 2:

Другой вариант - использовать пейджинг для чтения и обработки нескольких записей за раз.

Я не уверен в синтаксисе для oracle, но в SQL это будет выглядеть примерно так:

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

/// <summary>
 /// Gets a list of Customers by name (with paging)
 /// </summary>
 /// The Sage database to query
 /// The start index
 /// The end index
 /// The filter
 /// <returns>List of suppliers</returns>
 public static List<slcustomeraccount> GetCustomersByAccountNumber(SageDatabase oSageDatabase, int startIndex, int endIndex, string filter)
 {
 try
 {
 string query = @"
 SELECT * 
 FROM
 (
 SELECT [SLCustomerAccount].*, 
 ROW_NUMBER() OVER (ORDER BY [SLCustomerAccount].[CustomerAccountNumber]) AS RowNumber
 FROM [SLCustomerAccount] 
 LEFT JOIN [SLCustomerLocation]
 ON [SLCustomerAccount].[SLCustomerAccountID]
 = [SLCustomerLocation].[SLCustomerAccountID]
 AND [SLCustomerLocation].[SYSTraderLocationTypeID]=0
 WHERE [AccountIsOnHold]=0
 AND [CustomerAccountNumber] + ' ' + [CustomerAccountName] + ' ' + [CustomerAccountShortName] + ' ' + ISNULL([SLCustomerLocation].[PostCode], '') LIKE @Filter
 ) as p
 WHERE p.RowNumber BETWEEN @StartIndex AND @EndIndex
 ";

 using (SqlCommand oSqlCommand = new SqlCommand(query))
 {
 oSqlCommand.Parameters.AddWithValue("@StartIndex", startIndex + 1);
 oSqlCommand.Parameters.AddWithValue("@EndIndex", endIndex + 1);
 oSqlCommand.Parameters.AddWithValue("@Filter", String.Format("%{0}%", filter));

 using (DataTable dtSupplier = DataTier.ExecuteQuery(oSageDatabase.ConnectString, oSqlCommand))
 {
 return (from DataRow dr
 in dtSupplier.Rows
 select new SLCustomerAccount(dr, oSageDatabase)).ToList();
 }
 }

 }
 catch (Exception)
 {
 throw;
 }
 }
</slcustomeraccount>

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

поэтому сначала запустите, чтобы перейти к запросу 0 для индекса start, 100 для конечного индекса, например, затем обработать записи и увеличить свои переменные, чтобы получить следующую страницу результатов. например, 101 start, 201 end


Вы должны ограничить данные на стороне базы данных некоторым подходящим условием или TOP- статусом

Но по вашему запросу, если вы хотите сделать это при обслуживании, используйте приведенный ниже код

oraDataset.Tables[0].AsEnumerable().Take(300);

Вместо 300 вы можете поставить номер согласно вашему требованию


Вы должны ограничить данные на уровне базы данных, изменив свой запрос. Это можно сделать, так как WraithNath прокомментировал ваше сообщение, используя SELECT TOP.

licensed under cc by-sa 3.0 with attribution.