2016-04-23 43 views
-3

當我運行這個動作時,我收到了這條消息:「已經有一個打開的DataReader與這個Command相關聯,必須先關閉它。」一個開放的數據讀取器

我的代碼是:公共無效UpdatePoints(字符串rightScore,串rightWinner) {

cmd.CommandText = "select * from Users_Details"; 
    cmd.Connection = connection; 
    connection.Open(); 
    rdr = cmd.ExecuteReader(); 

    while (rdr.Read()) 
    { 

     int points=0; 
     string sql; 
     string hisScore = (string)rdr["lastbetscore"]; 
     string hisWinner = (string)rdr["lastbetwinner"]; 
     if (rightScore == hisScore) 
      points = points + 30; 
     if (rightWinner == hisWinner) 
     { 
      points = points + 20; 
     } 

     sql = "update Users_Details set lastgame_points='" + points + "', gamesplayed='" + ((int)rdr["gamesplayed"] + 1) + "',currentpoints='" + ((int)rdr["currentpoints"] + points) + "',pointsPG='" + (((int)rdr["currentpoints"] + points)/((int)rdr["gamesplayed"] + 1)) + "' where username='" + (string)rdr["username"] + "'"; 
     cmd.CommandText = sql; 
     cmd.ExecuteScalar(); 
    } 
    rdr.Close(); 
    connection.Close(); 
} 

回答

0

你應該創造而不是重用舊這裏一個新的命令實例:

sql = "update Users_Details set lastgame_points='" + points + "', gamesplayed='" + ((int)rdr["gamesplayed"] + 1) + "',currentpoints='" + ((int)rdr["currentpoints"] + points) + "',pointsPG='" + (((int)rdr["currentpoints"] + points)/((int)rdr["gamesplayed"] + 1)) + "' where username='" + (string)rdr["username"] + "'"; 
cmd.CommandText = sql; 
cmd.ExecuteScalar(); 

在另外,閱讀命令參數,自己格式化SQL字符串,可以打開SQL注入攻擊。

3

錯誤消息是非常具體的關於你做錯了什麼。您不能重複使用該命令或連接的另一個命令您正在從它讀取數據。您必須首先將所有數據讀取到List或其他數據結構,然後使用此List的每個元素更新db。

另外,考慮在交易

var transaction = connection.BeginTransaction(); 
... 
transaction.Commit(); 

這會加速你的更新,因爲交易將被創建並COMMITED只有一次,但其它方式交易將隱含在每個更新

創建執行你的語句
+0

我添加了它,但仍然收到錯誤消息 –

+0

現在,它會打印出「已經有一個與此連接關聯的打開的DataReader,必須先關閉」。 ?而不是「命令」? –

+0

我的第一個答案是錯誤的,因爲不僅可以重用命令,還可以重用連接。請查看更正的答案。 –