标识SQLite Android游标中列的数据类型

5vf7fwbs  于 2022-11-15  发布在  SQLite
关注(0)|答案(5)|浏览(180)

在Android中,有没有办法识别游标中列的数据类型?Cursor对象有许多方法来获取列名、列值。
我想找出列(文本、整数)等的SQLite数据类型……
我正在编写一个泛型函数来解析游标和执行操作。我将只获得一个SQL字符串作为函数的参数。

64jmpszr

64jmpszr1#

根据SQLite文档(http://www.sqlite.org/datatype3.html),SQLite中的列没有数据类型--这些列中的值具有数据类型。
除了整数主键列之外,SQLite版本3数据库中的任何列都可用于存储任何存储类的值。
如果您使用的是API11级或更高级别,则游标支持getType()(请参阅http://developer.android.com/reference/android/database/AbstractWindowedCursor.html#getType(int)).
如果您使用的是较早的API级别,并且您知道给定游标中的所有结果都来自同一个表,则可以执行以下操作(未测试):

// Assumes "cursor" is a variable that contains the cursor you're
// interested in.

String tableName = "..."; // The name of the table
SQLiteDatabase db = cursor.getDatabase();
String[] names = cursor.getColumnNames();

for (name : names) {
    Cursor typeCursor = 
        db.rawQuery("select typeof (" + name + ") from " + tableName;
    typeCursor.moveToFirst();
    Log.v("test", "Type of " + name + " is " + typeCursor.getString(0);
}

但是,如果传递的游标是(例如)连接两个或多个表的db.rawQuery()调用的结果,那么这将失败(我预计)。

ryhaxcpt

ryhaxcpt2#

答案或者说尼克,是好的。但如果你的数据库是空的,他的代码就会崩溃。我建议使用:

String Query = "PRAGMA table_info(my_table_name)"; 
Cursor my_cursor  = db.rawQuery(Query, null); 
my_cursor.moveToFirst();
Column_name = my_cursor.getString(my_cursor.getColumnIndex("name"));
Column_type = my_cursor.getString(my_cursor.getColumnIndex("type"));
jmp7cifd

jmp7cifd3#

我还没有测试,但请尝试使用cursor.getType(I)
就像这样:

public static List resultSetToArrayListAndroid(Cursor cursor) throws SQLException {
    int columns = cursor.getColumnCount();
    ArrayList list = new ArrayList();
    while (cursor.moveToNext()) {
        HashMap row = new HashMap(columns);
        for (int i = 1; i <= columns; ++i) {
            switch (cursor.getType(i))  {
                case Cursor.FIELD_TYPE_FLOAT:
                    row.put(cursor.getColumnName(i), cursor.getFloat(i));
                    break;
                case Cursor.FIELD_TYPE_INTEGER:
                    row.put(cursor.getColumnName(i), cursor.getInt(i));
                    break;
                case Cursor.FIELD_TYPE_STRING:
                    row.put(cursor.getColumnName(i), cursor.getString(i));
                    break;
            }
        }
        list.add(row);
    }
    return list;
}
hm2xizp9

hm2xizp94#

您应该使用来自SQLite数据库的meta data
http://developer.android.com/reference/java/sql/ResultSetMetaData.html
您可以通过在ResultSet()上使用getMetaData()来获取该项。
因此,您应该使用的不是在Android中使用SQLite数据库的通常方式,而是通常的JDBC方式:
1.获取连接(通过驱动程序管理器getConnection)
1.获取语句(通过Connection.createStatement)
1.获取结果集(通过Statement.ecuteQuery)
1.获取元数据(通过Resultset.getMetaData)
向您致敬,斯特凡

cu6pst1q

cu6pst1q5#

下面是一个用于游标的toList扩展函数:

fun Cursor.toList(): List<List<Any>> {
    fun getValues(cursor: Cursor, numberOfFields: Int): List<Any> {
        return (0 until numberOfFields).map { index ->
            when {
                cursor.getType(index) == Cursor.FIELD_TYPE_STRING -> {
                    cursor.getString(index)
                }
                cursor.getType(index) == Cursor.FIELD_TYPE_INTEGER -> {
                    cursor.getInt(index)
                }
                else -> {
                    throw Exception("Unknown type when trying to get value at cursor.")
                }
            }
        }
    }

    val list = generateSequence { if (this.moveToNext()) this else null }
        .map {
            getValues(it, this.columnCount)
        }
        .toList()
    return list
}

像这样打电话:

val results: List<List<Any>> = db.rawQuery("SELECT * FROM tableName", null).toList()
val firstResult = results[0]
val firstResultsFirstValue = firstResult[0]

确保在查询中设置您的实际表名,并根据需要向When函数添加更多类型。

相关问题