使用 c# 的 sqldatareader 中的 IndexOutOfRange 异常



我用c#创建了一个应用程序,在我的认证接口中,我有一个测试控件,我想知道配置文件用户。

我的数据库包含名为user的表,其中包含 4 列

(id_user,name ,mail, profile) 

这是我的代码

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)

系统。索引超出范围:索引在数组的边界之外

您只选择一个字段 (profile(,但您尝试在此处选择第 4 个字段(索引 3(:

return ( s.GetString(3));

除了返回s.GetString(0)强烈建议您:

  • 使用参数化 SQL -始终执行此操作,以防止 SQL 注入攻击,使代码更具可读性,并防止意外的文本转换问题
  • 如果未找到配置文件,则抛出异常或返回null,而不是返回字符串"false">
  • 对一次性内容(如SqlCommandSqlConnectionSqlDataReader(使用using语句,以确保适当地清理资源
  • 开始遵循 .NET 命名约定,使代码更具惯用

所以像这样:

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;
}
}
}
}

所以你想要第四行,而不是你尝试用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);

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

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

cmd.CommandText = "select profile from user where name = @login;";
cmd.Parameters.Add("@login, SqlDbType.NVarChar).Value = login;
SqlDataReader s = cmd.ExecuteReader();
while (s.Read())
{   
return  s[0].ToString();
}

SqlDataReader.GetString 的参数应该是列索引。您只选择一列,因此会出现异常。

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

将 SQL 更改为:

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

最新更新