2017-11-28 35 views
2

私は学生情報を持っているデータベースを持っていて、ランダムに生成されたグレードをそれぞれ追加したいと思います。 A-Fの間にランダムグレードの文字を生成するメソッドを作成しました。しかし異なる行ごとにC#でExecuteNonQueryを実行する

、私は私のデータベーステーブルは、学生が、私はそれぞれ別のコースに異なるグレードを与えたい同じグレードを取得取っているすべてのコースを更新します。

command.CommandText = "UPDATE CurrentCourses SET CurrenteGrade ='" + 
         RandomLetter(grades) + "'"; 

command.ExecuteNonQuery(); 

私は、別の行ごとにこのクエリを実行する方法があると私の問題を解決するだろうと考えています。しかし、私は本当にそれを働かせることはできませんでした。 Microsoft Accessを使用してデータベースを作成しました。

+0

テーブルにプライマリキーがありますか?キーを取得するために照会する必要がある場合は、各キーのwhere句を使用して更新を実行してください。また、SQLに値を連結する代わりに、SQLパラメーターを使用することも検討してください。 – juharr

+0

'RandomLetter'メソッドのコードも表示できますか? –

+1

アクセスDBを使用している場合は、なぜこれをMySqlとタグ付けしましたか? – juharr

答えて

0

のようなものを試していただきありがとうございます。

UPDATE CurrentCourses SET CurrenteGrade = (select top 1 gradeName from grades ORDER BY NEWID()) 

あなたのコードでは、学生向けに異なるコースを設定していません。クエリを実行する前に、クエリのグレードは1つで、すべての行が更新されるためです。

SQLを使用して簡単に実行できます。

2

文は、データベーステーブルのすべての行に影響更新:WHERE句を指定しない

"UPDATE CurrentCourses SET CurrenteGrade ='" + 
        RandomLetter(grades) + "'" 

は、このコードはランダムなグレードでループ内で毎回100回実行されますが、できることですべての行テーブルは最後に無作為化されたグレードを示します。最後のループがランダムなグレードとして 'E'を選択した場合、テーブルのすべての行はグレードEになります。前の5秒間にグレードが99回変更されています(コードは毎回変更されます)

sqlCommand.CommandText = "UPDATE CurrentCourses SET CurrenteGrade = ? WHERE Course_ID = ?"; 

そして、SqlCommandオブジェクトのパラメータを移入::。あなたが同じ学年にすべてのコースの行を変更したい場合は

)のコードが実行されて停止したとき、彼らは変更のみを停止実行している

sqlCommand.Parameters.AddWithValue("grade", RandomLetter(grades)); 
sqlCommand.Parameters.AddWithValue("course", "SoftwareEngineering101"); 

これは、あなたが何度も実行するようなものです(lo op多分)別のコースIDで毎回。考え方は、パラメータ値を変更してからクエリを再実行することです。

sqlCommand.CommandText = "UPDATE CurrentCourses SET CurrenteGrade = ? WHERE Course_ID = ?"; 
sqlCommand.Parameters.AddWithValue("grade", "a"); //dummy values 
sqlCommand.Parameters.AddWithValue("course", "a"); //dummy values 
//the loop does the real work, repeatedly overwiting param values and running: 
foreach(var course in myCoursesArray){ 
    sqlCommand.Parameters["grade"] = RandomLetter(grades); 
    sqlCommand.Parameters["course"] = course; 
    sqlCommand.ExecuteNonQuery() 
} 

アクセスするには? SQLのパラメータプレースホルダの場合は、?と同じ順序でパラメータを追加することが重要です。マークがSQLに表示されます。名前は無関係です - これは、sqlserverのようなより強力なDBシステムではそうではありません.SQLではパラメータの名前が付けられ、c#コードで指定された名前が問題になります。しかし、Accessベースのコードでは、ループの中でパラメータ値を新しい値で上書きするときに、名前に関する重要な唯一のことが使用されます。

注: .AddWithValueの使用を避けるべき十分な理由がありますが、私はここには入りません。文字列連結を使用してSQLに値を作成しないようにすることが重要です。詳細については、bobbytables.comを参照してください。

+0

RandomLetterは私にはC#のように思えますし、実行する前に、最新のCurrentCourses SET CurrenteGrade = 'SampleCourse'のようになります。ここにループはありません。これは、すべての行を同じコースとして更新する理由です。 – lucky

+0

もちろん、ループがあるとは言いませんでしたが、X回数だけ実行されるループがあっても、最後にループが実行されたときに選択された文字だけが表示されます –

+0

何かをする方法はありますか?(Where/CourseIdが違うときは)。私は既にCourseId列を持っているので、それぞれのコースごとにクエリを実行する方が簡単でしょうか。 – MG91

0

まず、あなたの正確な質問:更新を1行にフィルタリングするWHERE文が必要です。これは、通常、特定の行(この場合、学生)のID番号または他の一意の識別子で行われます。

第2の問題:生データと一緒に文字列を連結すると、エラーやセキュリティ上の問題が発生する可能性があります。たとえば、文字列データに一重引用符を付けるなどの不具合が発生します。 SqlParametersを使い果たすべきです。 https://www.dotnetperls.com/sqlparameter

0

最初に、学生とコースを含むテーブルの各行を照会することができます。

そして、データセットの各行に対して、その行をランダムな文字グレードで更新するメソッドを実行します。どんなWHERE句なしで、このUPDATEコマンドを使用して

foreach (DataRow dr in ds.tables[0].rows) 
{ 
    command.CommandText = "UPDATE CurrentCourses SET CurrenteGrade ='" + 
    RandomLetter(grades) + "'" + "WHERE PRIMARYKEY = dr.id" 
    command.ExecuteNonQuery(); 
} 
0

例えば

は、すべてのレコードたびに影響を与えます。照会が実行される前にランダムな文字がの前に生成されます()。したがって、クエリは1つの等級の文字で実行されます。

各コースごとにこのクエリを実行し、そのたびに1つのコースを選択する適切なWHERE句を使用できます。しかし、これは効率的ではありません。

さらに、SQL自体でランダムな関数を適用することもできます。これは各レコードについて評価されます(つまり、MySQLにランダムな等級を選択させる)。

UPDATE CurrentCourses 
SET CurrenteGrade = SUBSTRING('ABCDEF', FLOOR(RAND() * 6) + 1, 1) 
あなたのコードで

command.CommandText = @"UPDATE CurrentCourses 
    SET CurrenteGrade = SUBSTRING('ABCDEF', FLOOR(RAND() * 6) + 1, 1)"; 
command.ExecuteNonQuery(); 

これには、ループなしコマンドパラメータを必要としません。

RAND()は、0.0と1.0の間の乱数を返します(0.0を含みますが、1.0は含みません)。したがって、FLOOR(RAND() * 6)は[0 .. 5]の範囲の整数を生成します。文字が切り捨てられるSUBSTRING関数の場合、文字列'ABCDEF'のインデックスとして使用される[1..6]の範囲の数値を取得するために1が追加されます。

あなたが純粋なT-SQLでそれを行うことができます
0

declare @idColumn int 
DECLARE @MIN INT=1; --We define minimum value, it can be generated. 
DECLARE @MAX INT=100; --We define maximum value, it can be generated. 

select @idColumn = min(Id) from CurrentCourses 

while @idColumn is not null 
begin 
Update CurrentCourses 
SET CurrenteGrade = @MIN+FLOOR((@[email protected]+1)*RAND(CONVERT(VARBINARY,NEWID()))); 
    select @idColumn = min(Id) from CurrentCourses where Id > @idColumn 
end 

上記のコードは、すべてのレコードをループ(主キーとIdを置き換え)と1-100の間の乱数を生成している(ここでコメントを参照してください新しい値を設定することができます)、各CurrentGradeレコードの乱数を更新します。あなたのCommandTextに命じるとExecuteNonQuery()

0

を実行

フォーマットとCONCATENATE条件は、それがテーブル内のすべてのデータを更新しますあなたの更新query.WithoutにWHERE条件を入れてください。

関連する問題