0

此查询(方法 CalculateCGPA 中的命令)在 mysql Workbench 中运行良好。它仅返回包含 2.00 的 cgpa 的 1 行和 1 列。我想将它存储在我的 cgpa 字符串中,但它在这一行出现错误:cgpa = Convert.ToString(myReader.GetString(0));

错误说:“数据为 Null。不能对 Null 值调用此方法或属性。”

请注意,在进入程序上方的错误行之前,已经通过了 IF 语句测试,表明 READER 不为空。

有人可以帮助我吗?

public string GetStudentID()
        {
            List<string> list = new List<string>();

            conn.Open();
            string STDid = "SELECT Student_ID from Student";
            MySqlCommand cmd = new MySqlCommand(STDid, conn);
            MySqlDataReader myReader;
            myReader = cmd.ExecuteReader();

            while (myReader.Read())
            {
                list.Add(Convert.ToString(myReader.GetString(0)));

            }
            myReader.Close();
            conn.Close();

            string[] array = list.ToArray();


                string newcgpa = CalculateCGPA(array[0]);
                return newcgpa;



        }


        public string CalculateCGPA(string arrayElement)
        {
            string cgpa;
            conn.Open();
            string command = "SELECT ROUND((sum(enroll.Enroll_Grade_Point*course.Crs_Credits) /sum(course.Crs_Credits)),2) as CGPA FROM student, enroll, course, class Where student.Student_ID = enroll.Student_ID AND enroll.Class_Code = class.Class_Code and class.Crs_Code = course.Crs_Code and student.Student_ID = '" + arrayElement + "'";

 MySqlCommand cmd = new MySqlCommand(command, conn);
            MySqlDataReader myReader;
            myReader = cmd.ExecuteReader();
            if (myReader.Read())
            {
                cgpa = Convert.ToString(myReader.GetString(0));
                cmd.Connection.Close();
                myReader.Close();

                return cgpa;
            }
            else
            {
                cmd.Connection.Close();
                myReader.Close();
                return null;
            }
4

2 回答 2

1

不应在 DBNull 值上调用 myReader.GetString

 list.Add(Convert.ToString(myReader.GetString(0)));

试试这个

myReader.IsDBNull(myReader.GetString(0)) ? null : reader.GetString(0)
于 2013-06-30T09:50:05.100 回答
0

你说这个查询只返回一行一列。因此,在这种情况下,最好调用 ExecuteScalar 而不是构建阅读器,对其进行初始化并提取...。

 MySqlCommand cmd = new MySqlCommand(command, conn);
 object result = cmd.ExecuteScalar();
 if(result != null)
 {
    cpga = Convert.ToString(result);
 }

也不要使用字符串连接来构建 sql 字符串,而是使用参数化查询,因为您会受到 Sql 注入攻击

string command = "SELECT ROUND((sum(enroll.Enroll_Grade_Point*course.Crs_Credits) " + 
                 "/sum(course.Crs_Credits)),2) as CGPA FROM student, enroll, course, " + 
                 "class Where student.Student_ID = enroll.Student_ID AND " + 
                 "enroll.Class_Code = class.Class_Code and " + 
                 "class.Crs_Code = course.Crs_Code and " + 
                 "student.Student_ID = @element";

MySqlCommand cmd = new MySqlCommand(command, conn);
cmd.Parameters.AddWithValue("@element", arrayElement);

Student_ID 字段真的是字符串字段吗?如果它是数字,则将 arrayElement 转换为正确的数字类型 ( Convert.ToInt32(arrayElement))

但是,如果您仍想使用 MySqlDataReader 来取回该值,则添加一些完整性检查。

例如,SqlDataReader 文档建议在尝试调用 GetString() 之前 调用IsDBNull 。

相同的文档说,如果您尝试读取不是字符串的值,则可能会收到 InvalidCastException,因此不要调用 GetString(0) 然后 Convert.ToString(string) 直接返回带有 reader[0] 的数据对象和让转换发生在 Convert.ToString() 中。

我很确定这些建议对 MySqlDataReader 仍然有效.....

所以我会这样改变阅读线

cgpa = (myReader.IsDBNull(0) ? "0" : Convert.ToString(myReader[0]));

请注意,如果 myReader.Read 返回 true,这并不意味着 CPGA 不为空,因为表之间的连接可能会中断,并且 where 条件可能会排除每条记录。
查询中可能的更改可能是使用显式连接,但这不允许避免空检查。

string command = "SELECT ROUND((sum(e.Enroll_Grade_Point*c.Crs_Credits) " + 
                 "/sum(c.Crs_Credits)),2) as CGPA " + 
                 "FROM student s INNER JOIN enroll e ON s.Student_ID = e.Student_ID " + 
                 "INNER JOIN class c ON e.Class_Code = c.Class_Code " + 
                 "INNER JOIN course u ON c.Crs_Code = u.Crs_Code "
                 "WHERE s.Student_ID = @element";
于 2013-06-30T09:47:13.400 回答