简体   繁体   English

SqlDataReader不读取除第一行以外的任何行

[英]SqlDataReader not reading any row apart from first

New to stackoverflow and very much ac# beginner 是Stackoverflow的新手,并且是ac#初学者

Currently creating a form which produces a bar chart from data stored in a database. 当前正在创建一个表单,该表单从数据库中存储的数据生成条形图。 The chosen record is identified by pID (patient's ID) and tdate (Test date). 所选记录由pID(患者的ID)和tdate(测试日期)标识。 These values are determined by 2 combo boxes that the user can select from, The problem I am having is that only the first and last records stored in the database are populating the barchart. 这些值由2个组合框确定,用户可以从中选择。我遇到的问题是,只有存储在数据库中的第一条记录和最后一条记录正在填充条形图。

 if (radioButtonTestResult.Checked)
{
foreach (var series in TestResultBarChart.Series)
{
series.Points.Clear();
}
string tdate = comboBox2.Text;
using (SqlConnection connection = new SqlConnection(@"Data Source=               (LocalDB)\v11.0;AttachDbFilename=|DataDirectory|\MMSEDB.mdf;Integrated    Security=True"))
{
connection.Open();
string sql = "SELECT          T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,T_REGISTRATION_SCORE,T_ORIENTATION  _SCORE,T_TIME FROM TEST_RESULTS WHERE P_ID='" + pID + "' AND T_DATE='"+ tdate +"'";
 using(SqlCommand command = new SqlCommand(sql, connection))
{ 
command.CommandTimeout = 3600;             
using (SqlDataReader reader =     command.ExecuteReader(CommandBehavior.SequentialAccess))
    { 
while (reader.Read())
        {
              MessageBox.Show("hello4");
                String clockScoreString = reader["T_CLOCK_SCORE"].ToString();
                MessageBox.Show(clockScoreString);
                clockScore = Int32.Parse(clockScoreString);
                String langScoreString = reader["T_LANGUAGE_SCORE"].ToString();
                langScore = Int32.Parse(langScoreString);
                String recallScoreString = reader["T_RECALL_SCORE"].ToString();
                recallScore = Int32.Parse(recallScoreString);
                String regScoreString = reader["T_REGISTRATION_SCORE"].ToString();
                regScore = Int32.Parse(regScoreString);
                String orientScoreString = reader["T_ORIENTATION_SCORE"].ToString();
                orientScore = Int32.Parse(orientScoreString);
                String timeScoreString = reader["T_TIME"].ToString();
                timeScore = Int32.Parse(timeScoreString);
        }
        reader.Close(); 
    }
}  


this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score",     langScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);


}

        }

Here is a pic of the data: Test_results_table 这是数据的图片: Test_results_table

here is a pic of the interface with the first record working: interface 这是带有第一个记录的界面的照片: interface

I know this has something to do with the reader but can't work out how to get to function correctly 我知道这与读者有关,但无法弄清楚如何正确发挥作用

Any help is very much appreciated 很感谢任何形式的帮助

You are reading in a loop all the returned values, then exit from the loop and use just the last value to set your Points. 您正在循环读取所有返回的值,然后退出循环并仅使用最后一个值来设置点。 You should move the Point settings inside the loop 您应该在循环内移动Point设置

....
while (reader.Read())
{
    clockScore = Convert.ToInt32(reader["T_CLOCK_SCORE"]);
    langScore = Convert.ToInt32(reader["T_LANGUAGE_SCORE"]);
    recallScore = Convert.ToInt32(reader["T_RECALL_SCORE"]);
    regScore = Convert.ToInt32(reader["T_REGISTRATION_SCORE"]);
    orientScore = Convert.ToInt32(reader["T_ORIENTATION_SCORE"]);
    timeScore = Convert.ToInt32(reader["T_TIME"]);
    this.TestResultBarChart.Series["Series1"].Points.AddXY("Clock Score", clockScore);
    this.TestResultBarChart.Series["Series1"].Points.AddXY("Language Score",     langScore);
    this.TestResultBarChart.Series["Series1"].Points.AddXY("Recall Score", recallScore);
    this.TestResultBarChart.Series["Series1"].Points.AddXY("Registration Score", regScore);
    this.TestResultBarChart.Series["Series1"].Points.AddXY("Orientation Score", orientScore);            
}
reader.Close(); 

Note that your query is built using string concatenation. 请注意,您的查询是使用字符串连接构建的。 This is a well known problem with database code. 这是数据库代码的众所周知的问题。 Never do it and use a parameterized query 绝对不要使用参数化查询

EDIT 编辑
Looking at your comment below, I repeat the advice to use a parameterized query instead of string concatenation. 在下面查看您的评论时,我重复建议使用参数化查询而不是字符串连接。 Not only this avoid Sql Injection hacks but also you don't leave the job to understand the meaning of your values to the database engine 这不仅可以避免Sql Injection黑客攻击,而且您不必离开工作就可以了解数据库引擎的值的含义。

DateTime tDate = Convert.ToDateTime(comboBox2.Text);
......
string sql = @"SELECT 
                   T_CLOCK_SCORE,T_LANGUAGE_SCORE,T_RECALL_SCORE,
                   T_REGISTRATION_SCORE,T_ORIENTATION_SCORE,T_TIME 
               FROM TEST_RESULTS 
               WHERE P_ID=@id AND T_DATE=@date";

using(SqlCommand command = new SqlCommand(sql, connection))
{ 
     command.Parameters.Add("@id", SqlDbType.Int).Value = pID;
     command.Parameters.Add("@date", SqlDbType.Date).Value = tdate;
     command.CommandTimeout = 3600;             
     using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
     { 
          while (reader.Read())
          ....

In this example I assume that the variable pID is of type integer and the variable tDate is of type DateTime matching the type of the database fields. 在此示例中,我假定变量pID为整数类型,变量tDate为与数据库字段类型匹配的DateTime类型。 This doesn't leave any doubt to the database engine on your values. 这对您的值毫无疑问是数据库引擎。
Of course if the fields are of different type then you should change the SqlDbType accordingly. 当然,如果字段的类型不同,则应相应地更改SqlDbType。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM