การใช้ฟังก์ชัน typeof() ใน SQLite บน Android
ฟังก์ชัน typeof() ใน SQLite ใช้สำหรับตรวจสอบชนิดข้อมูล (Data Type) ของค่าในคอลัมน์ ซึ่งเป็นประโยชน์เมื่อต้องการทราบว่าข้อมูลที่จัดเก็บอยู่เป็นชนิดใด (TEXT, INTEGER, REAL, BLOB, NULL)
ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่
สร้างโปรเจกต์ Android ใหม่ใน Android Studio
ขั้นตอนที่ 2: ออกแบบ Layout (res/layout/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/etName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ป้อนชื่อ" />
<EditText
android:id="@+id/etSalary"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ป้อนเงินเดือน"
android:inputType="numberDecimal" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:orientation="horizontal">
<Button android:id="@+id/btnSave" android:text="บันทึก" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<Button android:id="@+id/btnRefresh" android:text="รีเฟรช" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<Button android:id="@+id/btnUpdate" android:text="อัปเดต" android:layout_width="wrap_content" android:layout_height="wrap_content" />
<Button android:id="@+id/btnDelete" android:text="ลบทั้งหมด" 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">
</ListView>
</LinearLayout>
ขั้นตอนที่ 3: MainActivity.java
package com.example.myapplication;
import android.os.Bundle;
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 androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private EditText etName, etSalary;
private ListView listView;
private ArrayAdapter<String> adapter;
private DatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new DatabaseHelper(this);
ArrayList<String> dataList = dbHelper.getAllTypeNames();
etName = findViewById(R.id.etName);
etSalary = findViewById(R.id.etSalary);
listView = findViewById(R.id.listView);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, dataList);
listView.setAdapter(adapter);
findViewById(R.id.btnDelete).setOnClickListener(v -> {
Toast.makeText(this, dbHelper.deleteAll() ? "ลบสำเร็จ" : "ลบไม่สำเร็จ", Toast.LENGTH_LONG).show();
});
findViewById(R.id.btnUpdate).setOnClickListener(v -> {
String name = etName.getText().toString().trim();
String salary = etSalary.getText().toString().trim();
if (!name.isEmpty() && !salary.isEmpty()) {
Toast.makeText(this, dbHelper.update(name, salary) ? "อัปเดตสำเร็จ" : "อัปเดตไม่สำเร็จ", Toast.LENGTH_LONG).show();
} else {
etName.setError("กรุณาป้อนชื่อ");
etSalary.setError("กรุณาป้อนเงินเดือน");
}
});
findViewById(R.id.btnRefresh).setOnClickListener(v -> {
dataList.clear();
dataList.addAll(dbHelper.getAllTypeNames());
adapter.notifyDataSetChanged();
});
findViewById(R.id.btnSave).setOnClickListener(v -> {
String name = etName.getText().toString().trim();
String salary = etSalary.getText().toString().trim();
if (!name.isEmpty() && !salary.isEmpty()) {
Toast.makeText(this, dbHelper.insert(name, salary) ? "บันทึกสำเร็จ" : "บันทึกไม่สำเร็จ", Toast.LENGTH_LONG).show();
} else {
etName.setError("กรุณาป้อนชื่อ");
etSalary.setError("กรุณาป้อนเงินเดือน");
}
});
}
}
ขั้นตอนที่ 4: DatabaseHelper.java - จุดสำคัญคือ Query ใช้ typeof()
package com.example.myapplication;
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 DB_NAME = "salaryDatabase";
private static final String TABLE_NAME = "SalaryDetails";
private static final int DB_VERSION = 1;
public DatabaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// salary ใช้ FLOAT (จะเก็บเป็น REAL ใน SQLite)
String sql = "CREATE TABLE " + TABLE_NAME + " (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, salary REAL, datetime DEFAULT CURRENT_TIMESTAMP)";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
public boolean insert(String name, String salary) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("salary", salary);
return db.insert(TABLE_NAME, null, values) != -1;
}
// จุดสำคัญ: ใช้ typeof(name) เพื่อดูชนิดข้อมูลของคอลัมน์ name
public ArrayList<String> getAllTypeNames() {
SQLiteDatabase db = getReadableDatabase();
ArrayList<String> list = new ArrayList<>();
// typeof() จะคืนค่า: 'text', 'integer', 'real', 'blob', หรือ 'null'
Cursor cursor = db.rawQuery("SELECT typeof(name) as type_name FROM " + TABLE_NAME, null);
if (cursor.moveToFirst()) {
do {
list.add("Chnid data type of name: " + cursor.getString(0));
} while (cursor.moveToNext());
}
cursor.close();
return list;
}
public boolean update(String name, String salary) {
SQLiteDatabase db = getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("salary", salary);
return db.update(TABLE_NAME, values, "name = ?", new String[]{name}) > 0;
}
public boolean deleteAll() {
return getWritableDatabase().delete(TABLE_NAME, null, null) > 0;
}
}
คำอธิบาย typeof()
- typeof(X) คืนค่าสตริงที่บ่งชี้ชนิดข้อมูลของ expression X
- ค่าที่เป็นไปได้:
'text','integer','real','blob','null' - ใน SQLite ชนิดข้อมูลเป็นแบบ Dynamic Typing - ชนิดข้อมูลขึ้นอยู่กับค่าที่จัดเก็บ ไใช่คอลัมน์
- แม้คอลัมน์จะประกาศเป็น TEXT แต่หากใส่ตัวเลขเข้าไป typeof() อาจคืนค่า 'integer' หรือ 'real'
ตัวอย่างผลลัพธ์
หากบันทึกชื่อ "Sairam" (เป็นข้อความ) ผลลัพธ์จาก typeof(name) จะเป็น text
ListView จะแสดง: "Chnid data type of name: text"
ประโยชน์ในการพัฒนา
- Debugging: ตรวจสอบว่าข้อมูลถูกจัดเก็บในชนิดที่คาดหวังหรือไม่
- Data Validation: ตรวจสอบก่อนทำการคำนวณหรือเปรียบเทียบ
- Migration: ตรวจสอบข้อมูลก่อนย้ายระหว่างระบบ