SQLite架构信息元数据

时间:2011-06-23 21:14:42

标签: sqlite information-schema

我需要在SQLite数据库中获取列名及其表。我需要的是一个包含2列的结果集:table_name | column_name

在MySQL中,我能够通过数据库INFORMATION_SCHEMA上的SQL查询获取此信息。但是SQLite提供了表sqlite_master

sqlite> create table students (id INTEGER, name TEXT);
sqlite> select * from sqlite_master;
  table|students|students|2|CREATE TABLE students (id INTEGER, name TEXT)

导致DDL构造查询(CREATE TABLE)对我没有帮助,我需要解析它以获取相关信息。

我需要获取表的列表并将它们与列连接,或者只是获取列和表名列。所以PRAGMA table_info(TABLENAME)对我不起作用,因为我没有表名。我想获取数据库中的所有列元数据。

通过查询数据库是否有更好的方法将结果集作为结果集获取?

7 个答案:

答案 0 :(得分:74)

你基本上已经在你的问题中命名了解决方案。

要获取表格(和视图)列表,请在

中查询sqlite_master
SELECT name, sql FROM sqlite_master
WHERE type='table'
ORDER BY name;

(见the SQLite FAQ

要获取有关特定表格中列的信息,请按the SQLite PRAGMA documentation中的说明使用PRAGMA table_info(table-name);

我不知道是否有任何方法可以将tablename | columnname作为单个查询的结果返回。我不相信SQLite支持这一点。您最好的选择可能是将这两种方法结合使用来返回您正在寻找的信息 - 首先使用sqlite_master获取表列表,然后使用PRAGMA table_info()循环遍历它们。

答案 1 :(得分:10)

有“.tables”和“.schema [table_name]”命令,它们为从“select * from sqlite_master;”获得的结果提供了一种分离的版本。

还有“pragma table_info([table_name]);”命令以获得更好的解析结果而不是构造查询:


sqlite> .tables
students
sqlite> .schema students
create table students(id INTEGER, name TEXT);
sqlite> pragma table_info(students);
0|id|INTEGER|0||0
1|name|TEXT|0||0

希望,它在某种程度上有所帮助......

答案 2 :(得分:4)

仅供参考,如果您使用的是.Net,则可以使用DbConnection.GetSchema方法检索通常位于INFORMATION_SCHEMA中的信息。如果你有一个抽象层,你可以为所有类型的数据库使用相同的代码(注意MySQL似乎是限制数组的前2个参数)。

答案 3 :(得分:4)

另一个有用的技巧是首先从sqlite_master获取所有表名。

然后对于每一个,触发查询“select * from t where 1 = 0”。如果你分析结果查询的结构 - 取决于你从哪个语言/ api调用它 - 你会得到一个描述列的丰富结构。

在python中

c = ...db.cursor()
c.execute("select * from t where 1=0");
c.fetchall();
print c.description;

尤拉伊

PS。我习惯使用'where 1 = 0',因为记录限制语法似乎从db到db不等。此外,一个好的数据库将优化这个永远错误的条款。

使用'limit 0'可以在SQLite中实现相同的效果。

答案 4 :(得分:4)

SQLite的最新版本允许您select against PRAGMA results now,这很容易:

SELECT 
  m.name as table_name, 
  p.name as column_name
FROM 
  sqlite_master AS m
JOIN 
  pragma_table_info(m.name) AS p
ORDER BY 
  m.name, 
  p.cid

其中p.cid保存CREATE TABLE语句的列顺序(零索引)。

David Garoutte回答了here,但是此SQL应该执行得更快,并且列是按架构排序的,而不是按字母顺序排序。

请注意,table_info还包含

  • type(数据类型,例如integertext
  • notnull(如果列具有1约束,则为NOT NULL
  • dflt_value(如果没有默认值,则为NULL
  • pk(如果列是表的主键,则为10

RTFM:https://www.sqlite.org/pragma.html#pragma_table_info

答案 5 :(得分:2)

试试这个sqlite表模式解析器,我实现了sqlite表解析器,用于解析PHP中的表定义。

它返回完整定义(唯一,主键,类型,精度,非空,引用,表约束......等)

https://github.com/maghead/sqlite-parser

语法遵循sqlite create table语句语法:http://www.sqlite.org/lang_createtable.html

答案 6 :(得分:0)

这是一个老问题,但由于查看次数我们正在添加问题,原因很简单大多数答案都告诉您如何在SQLite数据库中查找TABLE名称 当表名不在数据库中时你会做什么? 这发生在我们的应用程序中,因为我们以编程方式创建TABLES 所以下面的代码将处理当TABLE不在或由Database Enjoy

创建时的问题
    public void toPageTwo(View view){

    if(etQuizTable.getText().toString().equals("")){
        Toast.makeText(getApplicationContext(), "Enter Table Name\n\n"
                +"           OR"+"\n\nMake Table First", Toast.LENGTH_LONG 
   ).show();
        etQuizTable.requestFocus();
        return;
    }

    NEW_TABLE = etQuizTable.getText().toString().trim();
    db = dbHelper.getWritableDatabase();
    ArrayList<String> arrTblNames = new ArrayList<>();
    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();
        }
    }
    c.close();
    db.close();

    boolean matchFound = false;
    for(int i=0;i<arrTblNames.size();i++) {
        if(arrTblNames.get(i).equals(NEW_TABLE)) {
            Intent intent = new Intent(ManageTables.this, TableCreate.class 
   );
            startActivity( intent );
            matchFound = true;
        }
    }
    if (!matchFound) {
        Toast.makeText(getApplicationContext(), "No Such Table\n\n"
                +"           OR"+"\n\nMake Table First", Toast.LENGTH_LONG 
 ).show();
        etQuizTable.requestFocus();
    }
}