使用c#在sqldatareader中的IndexOutOfRange异常

时间:2018-05-04 13:00:31

标签: c# sqldatareader

我使用c#创建一个应用程序,在我的身份验证界面中,我有一个测试控件,我想知道配置文件用户。

我的数据库包含名为(id_user,name ,mail, profile) 的表,其中包含4列

public string profil_user(string login)
    {
        SqlConnection conn = new database().connect_user();
        SqlCommand cmd = conn.CreateCommand();
        cmd.CommandText = "select profile from user where name = '" + login + "';";
        SqlDataReader s = cmd.ExecuteReader();
        if (s.Read())
        {
           return ( s.GetString(3));


        }
        else{return ("false"); }
    }

这是我的代码

s.GetString(3)

但我在select **** COALESCE(Customers / (NULLIF(Visitors,0)),0) AS CR

中有例外
  

system.IndexOutOfRange:index超出了数组的范围

5 个答案:

答案 0 :(得分:2)

您只选择一个字段(profile),但是您在这里尝试选择第四个字段(索引3):

return ( s.GetString(3));

除了回复s.GetString(0)之外,我强烈建议您:

  • 使用参数化SQL - 始终执行此操作,以防止SQL injection attacks,使代码更具可读性,并防止意外的文本转换问题
  • 如果找不到配置文件,则抛出异常或返回null,而不是返回字符串“false”
  • usingSqlCommandSqlConnection等一次性内容使用SqlDataReader语句,以确保您正确清理资源
  • 开始关注.NET naming conventions以使您的代码更加惯用

类似于:

public string GetUserProfile(string login)
{
    string sql = select profile from user where name = @login";
    // I assume Connect() returns an *open* connection?
    using (var conn = new Database().Connect())
    {
        using (var command = new SqlCommand(sql, conn))
        {
            command.Parameters.Add("@login", SqlDbType.NVarChar).Value = login;
            using (var reader = command.ExecuteReader())
            {
                // If it's an error (code failure) for there to be no matching profile,
                // you may want to throw an exception instead.
                return s.Read() ? s.GetString(0) : null;
            }
        }
    }
}

答案 1 :(得分:2)

所以你想要第四行,而不是你试图用s.GetString(3)访问的第四列:

int rowNum = 0;
while(s.Read())
{
   if(++rowNum == 4)
   {
      return s.GetString(0);
   }
}
return "false";

但是,当您不使用Order By时访问第四行有点奇怪。您还应该只使用正确的sql查询返回所需的行。

如果你在这里使用字符串连接,你也可以打开sql注入:

cmd.CommandText = "select profile from user where name = '" + login + "';";

使用sql参数:

cmd.CommandText = "select profile from user where name = @login";
cmd.Parameters.Add("@login", SqlDbType.VarChar).Value = login;
  

有4列而不是行

好的,所以你想要第四列。你为什么不使用这个名字?

由于您只选择profile - 列(第四列),因此您只需使用GetString(0)即可。但您也可以选择所有列,然后使用GetOrdinal确定正确的索引:

int profileColumnIndex = s.GetOrdinal("profile");
return s.GetString(profileColumnIndex);

如果您不控制查询或将来可能会更改它,这将非常有用。

答案 2 :(得分:1)

因为您的选择列表中没有所有字段

将SQL更改为:

select id_user,name ,mail, profile from user where name = '" + login + "';

答案 3 :(得分:1)

您只选择1个字段,因此索引3超出范围。使用参数也非常重要。尝试:

@van:latin

答案 4 :(得分:1)

SqlDataReader.GetString的参数应该是列索引。您只选择一列,以便获得例外。