2017-04-27 7 views
1

私はMariaDBのテーブルを学生の学年で扱うつもりです。生徒が新しい成績を送るときは、最初に生徒の記録がテーブルにあるかどうかを確認する必要があります。はいの場合は、新しい成績が既存の成績より高い場合に更新します。生徒がテーブルに存在しない場合は、新しいレコードとして挿入します。続きこのジョブに対して1つのSQLクエリを書くことは可能ですか?select、then compare、insert/update

は($connmysqliオブジェクトで、簡単にするために、学生の名前はジョンと彼の新しいグレードが100であると仮定)私のPHPコードです:

$result = $conn->query("select name, grade from grade_sheet where name='john' and grade<100"); 

if ($result->num_rows > 0) { 
    $conn->query("update grade_sheet set grade=100 where name='john'"); 
} else { 
    $conn->query("insert into grade_sheet (name, grade) values ('john', 100)"); 
} 

は、コードを簡素化することが可能ですか?具体的には、insert ... on duplicate key updateのように使用できますか?

ここではnameが主キーです。最悪の場合、上記のコードはテーブルを2回検索する必要がありますか?

+0

コードはすでに簡単です。単一のSQL文でそれを作成しようとすると、読みやすく理解しにくくなります。それはすでに大丈夫です。あなたが1つのコードでそれを必要とするより具体的な理由はありますか? –

+0

@JorgeCampos 'insert ... duplicate key update'をここで使うことができますか?最悪の場合、上記のコードはテーブルを2回検索する必要がありますか? –

答えて

1

コメントに記載されているのとは違って、これは間違ったアプローチであり、あなたはこれを変更したいのです。あなたがそれを変更する必要がある理由は、競合状態、すなわち別のスレッドがあなたの2つのクエリの間に関心のあるレコードを変更する可能性を避けるためです。

パフォーマンスが悪い場合は、適切なインデックスがある場合は違いはありませんが、この種のクエリを実行している場合は、おそらくそうではありません。この表では、自動インクリメントの主キーが必要で、 'John'ではなくその列を使用して参照する必要があります。これは非常にユニークではありません。生徒の名前を記録する学生テーブルへの外部キーがあります。

次に、INSERT ... ON DUPLICATE KEY UPDATEを使用して、1つのクエリでジョブを完了させることができます。安全に。

+0

ありがとうございます。私は文書を読んだので、次のクエリは正しいです: '重複キーの更新グレード= if(グレード<100,100、グレード)' –

+0

でgrade_sheet(名前、グレード)の値( 'john'、100)生徒のID番号を一意のプライマリキーに使用しました。 –

+0

johnは一意ではないので、ここでは「john」の代わりに数字キーを使用します – e4c5

関連する問題