C#SqlCommand - 将结果集设置为变量

时间:2011-04-27 18:42:06

标签: c# sql

我在C#中运行一个返回一个值(String)的SQL命令。我然后尝试将其保存到变量,但它总是抛出此异常:

  

System.Data.dll中发生了'System.InvalidOperationException'类型的第一次机会异常       线程''(0x1bbc)已退出,代码为0(0x0)。       System.InvalidOperationException:没有数据时读取的尝试无效。          在System.Data.SqlClient.SqlDataReader.GetValue(Int32 i)

但是,当我在SQL Server中运行相同的命令时,它肯定会输出一个值。

myCommand = new SqlCommand("SELECT TrialName FROM dbo.CT WHERE NumId='"+TrialId+"'", myConnection);    
SqlDataReader dr = myCommand.ExecuteReader();  
String TName = dr[0].ToString(); 

即使我对整个sqlcommand进行硬编码(而不是使用TrialId变量),它仍会抛出异常。这是怎么回事?

4 个答案:

答案 0 :(得分:8)

在从数据阅读器读取之前,您必须先调用dr.Read():

myCommand = new SqlCommand("SELECT TrialName FROM dbo.CT WHERE NumId='"+TrialId+"'", 

myConnection);                
SqlDataReader dr = myCommand.ExecuteReader();                
if(dr.Read())
{
    String TName = dr[0].ToString(); 
}

SqlDataReader.Read()使读者前进到下一条记录,并在没有更多记录时返回false。

答案 1 :(得分:2)

正如其他答案所指出的,你需要在SqlDataReader上调用Read()方法。

但是,如果您只从select语句返回一个值,则应考虑使用SqlCommand.ExecuteScalar method。它不需要像使用SqlDataReader那样多的代码。

这样的事情:

string name = Convert.ToString(myCommand.ExecuteScalar());

答案 2 :(得分:1)

您需要先致电dr.Read()才能阅读。 DataReader.Read()将DataReader推进到下一行。您也必须在第一行调用它,以便可以在while循环中使用它:

while ( dr.Read() )
{
    ...
}

希望这有帮助!

答案 3 :(得分:0)

我可以建议使用参数化查询来帮助防范SQL注入漏洞吗?如果您需要ad-hoc SQL语句而不是存储过程,请考虑使用以下内容:

如果您只需要第一行的第一列值,则可以使用ExecuteScalar()命令:

string TName;        
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT TrialName FROM dbo.CT WHERE NumId=@Trial";
    cmd.Parameters.AddWithValue("@Trial", TrialId);
    TName = cmd.ExecuteScalar().ToString();
}

如果需要的值超过单个值,请继续使用SqlDataReader:

string TName;        
using (var conn = new SqlConnection(SomeConnectionString))
using (var cmd = conn.CreateCommand())
{
    conn.Open();
    cmd.CommandText = "SELECT TrialName FROM dbo.CT WHERE NumId=@Trial";
    cmd.Parameters.AddWithValue("@Trial", TrialId);
    using (var reader = cmd.ExecuteReader())
    {
        if (reader.Read())
        {
            TName  = reader["TrialName"].ToString();
        }
    }
}