如何在安卓SQLite数据库中获取所有表名?

46

我已经尝试过这段代码

Cursor c=db.rawQuery("SELECT name FROM sqlite_master WHERE type = 'table'",null);
c.moveToFirst();
while(!c.isAfterLast()){
    Toast.makeText(activityName.this, "Table Name=> "+c.getString(0), 
        Toast.LENGTH_LONG).show();
}

但是它会抛出错误:

"android.database.sqlite.SQLiteException: no such table: sqlite_master(code 1):, while 
compiling: SELECT name FROM sqlite_master WHERE type='table'"

如何获取所有表名?


2
你难道不应该知道你数据库中表的名称吗? - njzk2
1
我想动态创建表,这些表在数据库中不存在,因此我想要使用我的数据库中现有的表名。就像在MySQL中显示表一样。 - Sandeep
6个回答

79

已经检查、测试且可用。尝试使用此代码:

Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);

if (c.moveToFirst()) {
    while ( !c.isAfterLast() ) {
        Toast.makeText(activityName.this, "Table Name=> "+c.getString(0), Toast.LENGTH_LONG).show();
        c.moveToNext();
    }
}

我假设在某个时刻,你需要获取一个表格名称列表以便在ListView或其他地方展示,而不仅仅是显示一个Toast。

未经测试的代码。只是我脑海中浮现的。在生产应用程序中使用之前请先进行测试。 ;-)

如果是这种情况,请考虑对上面发布的代码进行以下更改:

ArrayList<String> arrTblNames = new ArrayList<String>();
Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type='table'", null);

    if (c.moveToFirst()) {
        while ( !c.isAfterLast() ) {
            arrTblNames.add( c.getString( c.getColumnIndex("name")) );
            c.moveToNext();
        }
    }

4
我不明白你的查询有何不同? - njzk2
2
大家好,@siddharthLele的查询也适用于iOS Sqlite,例如: FMResultSet *s=[database executeQuery:@"SELECT name FROM sqlite_master WHERE type='table'"]; while ([s next]) { NSLog(@"%@",[s stringForColumn:@"name"]);}可以通过字符串名称进行迭代。 祝编码愉快! - Vaibhav Limbani
@Pilpel:我没有看到任何遗漏。如果您已经测试并发现有遗漏,请告诉我,我会修复它。 - Siddharth Lele

11

将您的SQL语句更改为以下内容:

"SELECT name FROM sqlite_master WHERE type = 'table' AND name! = 'android_metadata' ORDER BY name"


8
获取表名及该表所有列的列表:
    public void getDatabaseStructure(SQLiteDatabase db) {

            Cursor c = db.rawQuery(
                    "SELECT name FROM sqlite_master WHERE type='table'", null);
            ArrayList<String[]> result = new ArrayList<String[]>();
            int i = 0;
            result.add(c.getColumnNames());
            for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
                String[] temp = new String[c.getColumnCount()];
                for (i = 0; i < temp.length; i++) {
                    temp[i] = c.getString(i);
                    System.out.println("TABLE - "+temp[i]);


                    Cursor c1 = db.rawQuery(
                            "SELECT * FROM "+temp[i], null);
                    c1.moveToFirst();
                    String[] COLUMNS = c1.getColumnNames();
                    for(int j=0;j<COLUMNS.length;j++){
                        c1.move(j);
                        System.out.println("    COLUMN - "+COLUMNS[j]);
                    }
                }
                result.add(temp);
            }
}

5

尝试在表名前面添加模式

schema.sqlite_master

来自SQL FAQ

如果您正在运行sqlite3命令行访问程序,则可以输入“.tables”以获取所有表的列表。或者您可以输入“.schema”以查看完整的数据库模式,包括所有表和索引。这些命令中的任何一个都可以跟随一个LIKE模式,该模式将限制显示的表。

从C/C++程序中(或使用Tcl/Ruby/Perl/Python绑定的脚本)可以通过对特殊表“SQLITE_MASTER”进行SELECT来访问表格和索引名称。每个SQLite数据库都有一个定义数据库模式的SQLITE_MASTER表。SQLITE_MASTER表如下所示:

CREATE TABLE sqlite_master ( type TEXT, name TEXT, tbl_name TEXT, rootpage INTEGER, sql TEXT );


谢谢 :( 但我已经创建了模式,但仍然无法工作。你能贴出从SQLite数据库Android获取所有表名的代码吗? - Sandeep
尝试一下 @Siddharth Lele 提到的方法。他添加了一个条件,因为你不知道是否会收到任何结果。如果失败了,那么替换游标查询:Cursor c = db.rawQuery("SELECT name FROM your_schema.sqlite_master WHERE type='table'", null); - AlexBcn
谢谢,但我已经尝试过使用my_schema.sqlite_master,但没有成功。非常感谢您宝贵的回复。 - Sandeep

2
尝试这个:

SELECT name FROM sqlite_master WHERE type = "table";

13
这似乎只是问题中代码的一个片段。一般来说,以“试试这个”开头表明回答者并没有自己尝试过。 - Jukka K. Korpela

0

我用 Kotlin 和 Room 测试了 Siddharth Lele 的答案,它也能正常工作。

使用 Kotlin 和 Room 的相同代码大致是这样的:

val cursor = roomDatabaseInstance.query(SimpleSQLiteQuery("SELECT name FROM sqlite_master WHERE type='table' AND name NOT IN ('android_metadata', 'sqlite_sequence', 'room_master_table')"))
val tableNames = arrayListOf<String>()
if(cursor.moveToFirst()) {
   while (!cursor.isAfterLast) {
      tableNames.add(cursor.getString(0))
      cursor.moveToNext()
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接