上一篇
在安卓应用中获取SQLite数据库表字段的数据类型,可通过查询
sqlite_master表获取建表语句解析,或使用
Cursor.getType(int columnIndex)方法直接读取查询结果中某列的数据类型。
在Android应用开发中,直接获取SQLite数据库表字段的数据类型需要通过查询数据库的元数据(metadata)实现,由于SQLite采用动态类型系统(Type Affinity),其数据类型处理与其他关系型数据库(如MySQL)有所不同,下面是完整的技术实现方案:
核心原理:查询 sqlite_master 与 PRAGMA table_info()
SQLite数据库存储表结构信息的两种方式:

- 系统表
sqlite_master:保存所有表/索引的DDL语句 - PRAGMA命令:
PRAGMA table_info(table_name)返回字段定义详情
分步骤实现代码(Java/Kotlin)
步骤1:获取数据库引用
val dbHelper = MyDatabaseHelper(context) // 自定义SQLiteOpenHelper val db = dbHelper.readableDatabase
步骤2:执行 PRAGMA 查询目标表结构
// 以 "users" 表为例
val cursor = db.rawQuery("PRAGMA table_info(users)", null)
步骤3:解析Cursor中的数据类型
关键列说明:

name:字段名称 (String)type:数据类型声明 (String)notnull:是否非空 (Int, 0=false,1=true)pk:是否主键 (Int)
if (cursor.moveToFirst()) {
do {
val columnName = cursor.getString(cursor.getColumnIndexOrThrow("name"))
val dataType = cursor.getString(cursor.getColumnIndexOrThrow("type"))
// 输出示例:Column: email, Type: TEXT
Log.d("DB_SCHEMA", "Column: $columnName, Type: $dataType")
} while (cursor.moveToNext())
}
cursor.close()
处理SQLite动态类型的注意事项
Type Affinity 规则
| 声明的类型 | 关联类型(实际存储) |
|---|---|
INT, INTEGER |
INTEGER |
TEXT, VARCHAR |
TEXT |
REAL, FLOAT |
REAL |
BLOB |
BLOB |
| 未声明或其它类型 | NUMERIC |
例如声明为
VARCHAR(100)的字段,通过PRAGMA查询返回的type值为VARCHAR(100),但其亲和类型为TEXT
类型字符串可能包含修饰符
// 示例返回值可能为: // "INTEGER PRIMARY KEY" // "VARCHAR(50) NOT NULL"
建议的数据类型映射方法
fun mapToStdType(declaredType: String): String {
return when {
declaredType.contains("INT") -> "INTEGER"
declaredType.contains("CHAR") || declaredType.contains("TEXT") -> "TEXT"
declaredType.contains("BLOB") -> "BLOB"
declaredType.contains("REAL") || declaredType.contains("FLOAT") -> "REAL"
else -> "NUMERIC"
}
}
完整工具类实现(Kotlin)
object DbSchemaUtils {
fun getTableColumns(db: SQLiteDatabase, tableName: String): Map<String, String> {
val columns = mutableMapOf<String, String>()
val cursor = db.rawQuery("PRAGMA table_info($tableName)", null)
cursor.use {
while (it.moveToNext()) {
val name = it.getString(it.getColumnIndexOrThrow("name"))
val type = it.getString(it.getColumnIndexOrThrow("type"))
columns[name] = parseDataType(type)
}
}
return columns
}
private fun parseDataType(rawType: String): String {
val upperType = rawType.uppercase()
return when {
upperType.contains("INT") -> "INTEGER"
upperType.contains("CHAR") || upperType.contains("TEXT") -> "TEXT"
upperType.contains("BLOB") -> "BLOB"
upperType.contains("REAL") || upperType.contains("FLOAT") -> "REAL"
else -> "NUMERIC"
}
}
}
// 使用示例
val columns = DbSchemaUtils.getTableColumns(db, "orders")
columns.forEach { (name, type) ->
println("$name : $type")
}
重要技术提示
- 权限要求:应用需拥有数据库文件访问权限(通常位于
/data/data/your.package/databases/) - 异常处理:务必添加
try-catch块处理SQLiteException - 性能考量:PRAGMA查询在本地执行,无显著性能开销
- SQLCipher注意:加密数据库需使用
PRAGMA兼容版本
替代方案对比
| 方法 | 优点 | 缺点 |
|---|---|---|
PRAGMA table_info |
官方支持,结果标准化 | 需手动解析类型字符串 |
查询 sqlite_master |
可获取完整DDL语句 | 需要解析复杂SQL语句 |
| ORM框架(如Room) | 自动类型映射 | 强耦合框架,灵活性降低 |
适用场景建议
- 数据库迁移时动态获取表结构
- 自动生成数据模型类(Model Classes)
- 运行时验证字段类型兼容性
- 不应替代静态Schema定义(编译期已知结构)
引用说明:
本文技术方案基于SQLite官方文档《Datatypes In SQLite》及Android开发者文档《SQLiteDatabase》实现,类型映射规则遵循标准亲和性(Affinity)规范,测试验证于Android 10+ (API 29) 设备环境。

