在C#中,我在代码中使用TRY..CATCH..FINALLY
块来执行存储过程。
如果有异常,那么在我的FINALLY
我想要关闭阅读器 - PolicyResult
以及连接。
然而,我收到错误
当前上下文中不存在名称PolicyResult
PolicyResult
是TRY
中定义的DataReader,但在FINALLY
部分似乎无法识别。
为什么?
public static IEnumerable GetPolicies(int? MasterPkgID)
{
// Create a list of policies belonging to the master package.
List<AdditionalInterestPolicyData> additionalInterestPolicyData = new List<AdditionalInterestPolicyData>();
// Set the SQL connection to the database.
SqlConnection objConn = new SqlConnection(ConfigurationManager.ConnectionStrings["QUESTIONNAIRE2"].ConnectionString);
try
{
// Open the connection.
objConn.Open();
// Get the list of policies by executing a stored procedure.
SqlCommand PolicyCmd = new SqlCommand("p_expapp_get_policy_detail_by_master_pkg", objConn);
PolicyCmd.Parameters.Clear();
PolicyCmd.CommandType = CommandType.StoredProcedure;
PolicyCmd.Parameters.Add("@a_master_package_iden_key", SqlDbType.Int).Value = MasterPkgID;
SqlDataReader PolicyResult = PolicyCmd.ExecuteReader();
// Loop thru the results returned.
while (PolicyResult.Read())
{
// Add to the list of policies - creates a new row for the collection.
additionalInterestPolicyData.Add(new AdditionalInterestPolicyData(
Int32.Parse(PolicyResult["affiliate_id"].ToString()),
Int32.Parse(PolicyResult["master_package_iden_key"].ToString())
)
);
}
}
catch (Exception ex)
{
bError = true;
}
finally
{
PolicyResult.Close();
objConn.Close();
}
return additionalInterestPolicyData;
}
}
答案 0 :(得分:5)
考虑使用using
关键字
using (System.Data.SqlClient.SqlDataReader r = PolicyCmd.ExecuteReader())
{
//DO STUFF
}
您还可以为using
和SqlConnection
对象定义SqlCommand
范围。关闭范围后,将丢弃对象。
using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection())
{
...
using (System.Data.SqlClient.SqlCommand command = new System.Data.SqlClient.SqlCommand())
{
...
using (System.Data.SqlClient.SqlDataReader reader = new System.Data.SqlClient.SqlDataReader())
{
//DO STUFF
}
}
}
答案 1 :(得分:4)
因为您在try块中声明的所有内容在除嵌套和父级之外的其他块中不可见。在外面宣布它。
SqlDataReader PolicyResult=null;
try
{
...
PolicyResult = PolicyCmd.ExecuteReader();
}
比检查它是否为空
finally
{
if(PolicyResult!=null) PolicyResult.Close();
objConn.Close();
}
答案 2 :(得分:1)
PolicyResult在try块的范围内定义,因此在它之外不可用(例如,在finally块中。
答案 3 :(得分:1)
<{1}}中定义的只有<{> try {...}
才可见。如果您想访问try { ... }
区块中的PolicyResult
,则需要在<{em>} 区块内声明
执行此操作的首选方法是使用finally
块,但这会自动保证正确处理并基本上使try { ... }
块过时:
using (....) { .... }
答案 4 :(得分:0)
错误是正确的,它确实不存在,因为当您使用try / catch创建范围时,在该范围外创建的任何变量都不会在范围之外被识别。
您可以通过在 try / catch块之前将变换移动到来轻松解决此问题:
SqlDataReader PolicyResult;
// Other variable declerations
try
{
}
finally
{
// PolicyResult was decleared OUTSIDE the try block so it is known here.
}
答案 5 :(得分:0)
在PolicyResult
声明之前定义try
:
SqlDataReader PolicyResult = null;
答案 6 :(得分:0)
如果你想在catch和/或最后使用它,那么在try块之前声明SqlDataReader PolicyResult
答案 7 :(得分:0)
PolicyResult对象在 try 块的范围内声明,因此它不存在或无法从 finally 块中访问。将声明移到try连接对象声明旁边的try。
答案 8 :(得分:0)
try {}定义了与finally {}
分开的范围您必须在try之外声明PolicyResult,最后将其初始化为null,并在关闭之前检查是否为null。
答案 9 :(得分:0)
那是因为他们处于不同的范围。
尝试在try catch之前声明变量:
SqlDataReader PolicyResult;
try
{
// assign PolicyResult
}
catch
{
}
finally
{
// use PolicyResult
}
答案 10 :(得分:0)
您至少需要在try块之外声明PolicyResult,我建议也在外面实例化它。这样的事情应该有效:
public static IEnumerable GetPolicies(int? MasterPkgID)
{
// Create a list of policies belonging to the master package.
List<AdditionalInterestPolicyData> additionalInterestPolicyData = new List<AdditionalInterestPolicyData>();
// Set the SQL connection to the database.
SqlConnection objConn = new SqlConnection(ConfigurationManager.ConnectionStrings["QUESTIONNAIRE2"].ConnectionString);
SqlDataReader PolicyResult = null;
try
{
// Open the connection.
objConn.Open();
// Get the list of policies by executing a stored procedure.
SqlCommand PolicyCmd = new SqlCommand("p_expapp_get_policy_detail_by_master_pkg", objConn);
PolicyCmd.Parameters.Clear();
PolicyCmd.CommandType = CommandType.StoredProcedure;
PolicyCmd.Parameters.Add("@a_master_package_iden_key", SqlDbType.Int).Value = MasterPkgID;
PolicyResult = PolicyCmd.ExecuteReader();
// Loop thru the results returned.
while (PolicyResult.Read())
{
// Add to the list of policies - creates a new row for the collection.
additionalInterestPolicyData.Add(new AdditionalInterestPolicyData(
Int32.Parse(PolicyResult["affiliate_id"].ToString()),
Int32.Parse(PolicyResult["master_package_iden_key"].ToString())
)
);
}
}
catch (Exception ex)
{
bError = true;
}
finally
{
if(PolicyResult != null) PolicyResult.Close();
objConn.Close();
}
return additionalInterestPolicyData;
}
值得注意的是,这可能不是最好的方法。首先,您应该已经打开了数据库连接。打开和关闭每个事务的数据库连接非常快速。您可以轻松忘记关闭连接,如果出现错误,则可以根据上下文进行操作。如果这是一个Web应用程序,最好通过会话管理系统初始化连接,该会话管理系统将在页面加载时或第一个查询执行后立即打开连接。这样,您的连接打开和关闭逻辑就在一个地方。然后可以安全地假设连接确实在任何后续代码中连接,并且您可以更轻松地处理任何特定于事务的错误。