我遇到了存储过程的问题我尝试从ASP.NET控制台应用程序运行。
这就是我试图在代码中获得结果的方式:
public static DataTable PerformStoredProcedure(int PracticeID, string CommandName)
{
DataTable dt = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["DbConnString"].ToString()))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = CommandName;
cmd.Parameters.AddWithValue("@practiceID", PracticeID);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++)
{
Console.Write(dt.Rows[i].ItemArray[j] + ",");
}
Console.WriteLine();
}
}
}
运行程序后,我返回一个没有错误的空白数据集。但是,当我在SQL Server Management Studio中运行该过程时,我的工作正常。
您可能会注意到在启动new SqlCommand()
时我没有使用SqlCommand cmd
构造函数。这是因为查询非常庞大,需要一段时间才能运行,因此我认为这是一个超时问题。
根据建议here,我创建了以下类以调整执行超时限制。
class CommandFactory
{
public static int CommandTimeout
{
get
{
int commandTimeout = 0;
var configValue = ConfigurationManager.AppSettings["commandTimeout"];
if (int.TryParse(configValue, out commandTimeout))
return commandTimeout;
return 120;
}
}
我想包括这一点,以避免混淆SqlCommand
是否正确初始化。在调整之后,我开始遇到命令返回空白数据表的问题。我认为这可能与数据表dt
的最小容量有关,因此我在原始代码中进行了调整。
我已经做了额外的研究,并提出了建议无效的建议修补程序:
1.在
上设置nocount2.使用数据适配器而不是数据读取器
3.这是最详细的答案。在论坛中提出了一些建议,但最终解决方案与数据库默认使用的视图和阻止访问所需数据有关。我已经与DBA确认我们不会这样做。
就像我之前提到的那样,存储过程中包含的查询是巨大的,我还没有把它包含在这里,因为它的大小很大,因为这个帖子足够长。我再次确认该程序在SSMS中有效。
我还没有包含示例结果集,因为数据包含受限制的信息。
感谢您提供的任何帮助。
更新:
我添加了另一个调用存储过程的方法,以查看问题是否特定于被调用的特定过程。第二个存储过程也返回了一个空白数据表,因此问题不是特定于任何一个过程。 (我还确认第二个程序正在工作并在SSMS中返回行)
这让我相信该项目的app.config文件有问题。然后我添加了第三个方法,在解决方案中的另一个项目上调用存储过程。但是,即使返回了空白数据表。
想象一下,当我发现它们时,我会提供线索。
答案 0 :(得分:1)
你很亲密。以下是一些指示:
SqlConnection
。您需要按顺序拨打.Open()
建立连接。.Fill()
行上的断点并将鼠标悬停在DataTable
上
对象,它看起来好像DataTable
为空(如您所见),但.Fill()
实际填充了Rows
DataTable
为您
自动(见MSDN)。我敢打赌,如果你循环通过Rows
,你会发现
您的查询实际上一直在返回数据。using
语句自动为您调用.Dispose()
并关闭SqlConnection
。以下是您的方法的更新版本:
public static DataTable getAllModifiedChargesToday(int practiceID)
{
DataTable dt = new DataTable();
try
{
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.AppSettings["DbConnString"].ToString()))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "ch_getAllModifiedChargesToday";
cmd.Parameters.AddWithValue("@practiceID", practiceID);
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
{
da.Fill(dt);
}
}
}
}
catch (Exception ex)
{
LogError(ex);
}
return dt;
}
这是一个可以运行以查看返回数据的测试:
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Rows[i].ItemArray.Length; j++)
{
Console.Write(dt.Rows[i].ItemArray[j] + ",");
}
Console.WriteLine();
}
另外,你提到设置超时...我通常在我的连接字符串中设置我,如下所示:
"Server=SERVER;Database=DATABASE;User ID=USER;Password=PASSWORD;Trusted_Connection=False;Asynchronous Processing=true;Timeout=60;"
您根本不需要额外的CommandFactory
课程,除非您真的想要优化效果,否则您不需要设置MinimumCapacity
(MSDN)估计将返回多少条记录。此属性不常使用。