在我们的C#服务中,我需要为应用程序崩溃方案提供快速修复。
当尝试运行存储过程时,服务崩溃,因为它返回了大量数据。我们正在考虑限制服务方面的结果集。
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
数据库仍然完全执行proc,这很糟糕,但我们现在没有时间修复它。我们需要将检索到的数据限制为C#服务,从而防止崩溃。
我们如何限制数据?请注意,如果可以使用数据集,我们必须将其作为在服务器中传递的数据集。但如果没有别的办法,我可以重构代码。
答案 0 :(得分:3)
选项1:
您可以在存储过程中使用SELECT TOP xxx吗?
这将返回查询的第一个xxxx记录数,允许您指定限制。
您可能想要考虑使用不同的存储过程来使用有限的结果集调用服务,以便其他查询返回所有数据,或者使存储过程具有要作为可选参数返回的记录数。 / p>
选项2:
另一个选择是使用分页一次读取和处理多个记录。
我不确定oracle的语法,但它在SQL中看起来像这样:
这可能是一个更好的选择,因为您仍在处理查询中的所有记录,而不是一次处理所有记录。
/// <summary>
/// Gets a list of Customers by name (with paging)
/// </summary>
/// <param name="oSageDatabase">The Sage database to query</param>
/// <param name="startIndex">The start index</param>
/// <param name="endIndex">The end index</param>
/// <param name="filter">The filter</param>
/// <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;
}
}
这将允许你从SQL循环说出100条记录,这将有助于内存等,这取决于你对数据的处理。
所以首先运行你将传入查询0表示开始索引,100表示结束索引,然后处理记录,并增加变量以获得下一页结果。例如101开始,201结束
答案 1 :(得分:0)
您应该通过修改查询来限制数据库级别的数据。正如WraithNath通过使用SELECT TOP
语句对您的帖子所评论的那样,这可以完成。
答案 2 :(得分:0)
您应该使用一些适当的条件或TOP 语句来限制数据库端的数据
但是根据您的要求,如果您想在服务时使用以下代码
oraDataset.Tables[0].AsEnumerable().Take(300);
而不是300,您可以根据您的要求输入数字