Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách sử dụng UPDATE command trong SQLite Android

Lệnh UPDATE trong SQLite Android

Lệnh UPDATE sửa đổi dữ liệu hiện có trong bảng. Khác với REPLACE, UPDATE chỉ thay đổi các cột được chỉ định, giữ nguyên các cột khác và PRIMARY KEY.

Bước 1: Tạo dự án

Android Studio → File → New Project.

Bước 2: Giao diện (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Nhập tên" />
    <EditText android:id="@+id/salary" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Nhập lương" android:inputType="numberDecimal" />

    <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" android:layout_marginTop="8dp">
        <Button android:id="@+id/save" android:text="Lưu" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <Button android:id="@+id/refresh" android:text="Làm mới" android:layout_width="wrap_content" android:layout_height="wrap_content" />
        <Button android:id="@+id/update" android:text="Cập nhật" android:layout_width="wrap_content" android:layout_height="wrap_content" />
    </LinearLayout>

    <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" />
</LinearLayout>

Bước 3: MainActivity.java

package com.example.sqliteupdate;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {
    Button btnSave, btnRefresh, btnUpdate;
    EditText edtName, edtSalary;
    ListView listView;
    DatabaseHelper dbHelper;
    ArrayList dataList;
    ArrayAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbHelper = new DatabaseHelper(this);
        dataList = new ArrayList<>(dbHelper.getAllContacts());
        
        edtName = findViewById(R.id.name);
        edtSalary = findViewById(R.id.salary);
        listView = findViewById(R.id.listView);
        btnSave = findViewById(R.id.save);
        btnRefresh = findViewById(R.id.refresh);
        btnUpdate = findViewById(R.id.update);

        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
        listView.setAdapter(adapter);

        btnRefresh.setOnClickListener(v -> refreshList());
        
        btnSave.setOnClickListener(v -> {
            String name = edtName.getText().toString().trim();
            String salary = edtSalary.getText().toString().trim();
            if (name.isEmpty() || salary.isEmpty()) {
                showError(name, salary);
                return;
            }
            if (dbHelper.insert(name, salary)) {
                Toast.makeText(this, "Đã thêm", Toast.LENGTH_SHORT).show();
                refreshList();
            } else {
                Toast.makeText(this, "Thêm thất bại", Toast.LENGTH_SHORT).show();
            }
        });

        btnUpdate.setOnClickListener(v -> {
            String name = edtName.getText().toString().trim();
            String salary = edtSalary.getText().toString().trim();
            if (name.isEmpty() || salary.isEmpty()) {
                showError(name, salary);
                return;
            }
            // UPDATE: Cập nhật salary cho bản ghi có name tương ứng
            if (dbHelper.updateByName(name, salary)) {
                Toast.makeText(this, "Đã cập nhật lương cho: " + name, Toast.LENGTH_SHORT).show();
                refreshList();
            } else {
                Toast.makeText(this, "Không tìm thấy: " + name, Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void refreshList() {
        dataList.clear();
        dataList.addAll(dbHelper.getAllContacts());
        adapter.notifyDataSetChanged();
    }

    private void showError(String name, String salary) {
        if (name.isEmpty()) edtName.setError("Nhập tên");
        if (salary.isEmpty()) edtSalary.setError("Nhập lương");
    }
}

Bước 4: DatabaseHelper.java - UPDATE an toàn

package com.example.sqliteupdate;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;

public class DatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "salaryDatabase";
    private static final String TABLE_NAME = "SalaryDetails";
    private static final int DB_VERSION = 1;

    public DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DB_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE " + TABLE_NAME + 
            "(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, salary TEXT)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    public boolean insert(String name, String salary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", name);
        cv.put("salary", salary);
        return db.insert(TABLE_NAME, null, cv) != -1;
    }

    public ArrayList getAllContacts() {
        ArrayList list = new ArrayList<>();
        SQLiteDatabase db = getReadableDatabase();
        // Lọc: salary > 10 HOẶC name bắt đầu bằng 'Sa'
        Cursor cursor = db.rawQuery(
            "SELECT name FROM " + TABLE_NAME + 
            " WHERE salary > '10' OR name LIKE 'Sa%'", null);
        if (cursor.moveToFirst()) {
            do {
                list.add(cursor.getString(cursor.getColumnIndex("name")));
            } while (cursor.moveToNext());
        }
        cursor.close();
        return list;
    }

    // UPDATE AN TOÀN: Dùng ContentValues + whereClause + whereArgs
    public boolean updateByName(String name, String newSalary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("salary", newSalary);
        
        // WHERE name = ? - dùng tham số tránh SQL Injection
        int rowsAffected = db.update(TABLE_NAME, cv, "name = ?", new String[]{name});
        return rowsAffected > 0;
    }

    // UPDATE NHIỀU CỘT
    public boolean updateFull(String name, String newName, String newSalary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("name", newName);
        cv.put("salary", newSalary);
        return db.update(TABLE_NAME, cv, "name = ?", new String[]{name}) > 0;
    }

    // UPDATE CÓ ĐIỀU KIỆN PHỨC TẠP
    public boolean updateSalaryWhere(String condition, String[] args, String newSalary) {
        SQLiteDatabase db = getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put("salary", newSalary);
        return db.update(TABLE_NAME, cv, condition, args) > 0;
    }

    public boolean deleteAll() {
        return getWritableDatabase().delete(TABLE_NAME, null, null) > 0;
    }
}

Cú pháp UPDATE đầy đủ

-- Cú pháp cơ bản
UPDATE table_name 
SET column1 = value1, column2 = value2, ...
WHERE condition;

-- Ví dụ
UPDATE SalaryDetails 
SET salary = '5000', updated_at = CURRENT_TIMESTAMP 
WHERE name = 'An';

-- UPDATE với subquery
UPDATE SalaryDetails 
SET salary = salary * 1.1 
WHERE id IN (SELECT id FROM SalaryDetails WHERE department = 'IT');

-- UPDATE JOIN (SQLite hỗ trợ qua subquery)
UPDATE SalaryDetails 
SET bonus = (SELECT rate FROM BonusRate WHERE level = SalaryDetails.level)
WHERE EXISTS (SELECT 1 FROM BonusRate WHERE level = SalaryDetails.level);

Best Practices quan trọng

  1. Luôn dùng WHERE - Không có WHERE = cập nhật TẤT CẢ hàng.
  2. Dùng ContentValues + whereArgs - Tránh SQL Injection, xử lý escape tự động.
  3. Kiểm tra rowsAffected - Trả về số dòng bị ảnh hưởng, 0 = không tìm thấy.
  4. Transaction cho batch update:
db.beginTransaction();
try {
    for (Item item : items) {
        ContentValues cv = new ContentValues();
        cv.put("status", item.status);
        db.update(TABLE, cv, "id = ?", new String[]{String.valueOf(item.id)});
    }
    db.setTransactionSuccessful();
} finally {
    db.endTransaction();
}

⚠️ Lỗi thường gặp

  • Quên WHERE → update toàn bảng.
  • Ghép chuỗi SQL: "UPDATE ... SET salary = '" + salary + "'" → SQL Injection, lỗi quote.
  • UPDATE cột PRIMARY KEY → lỗi hoặc thay đổi identity.
  • Không kiểm tra kết quả → im lặng khi không update được gì.

So sánh: db.update() vs db.execSQL()

Phương thứcƯu điểmNhược điểm
db.update()An toàn, tự escape, trả về rows affectedChỉ UPDATE đơn giản
db.execSQL()Linh hoạt, subquery, expression phức tạpRủi ro SQL Injection, không trả về rows affected