如何获取给定表的索引列的列表

时间:2012-11-16 23:39:30

标签: c# sqlite

给定一个SQLite数据库,我需要获取一个列表,列出给定表中的哪些列被索引,以及排序顺序。我需要从代码中执行此操作(C#,尽管这不重要),所以我真正需要的是一个SQL语句,如果存在,则执行此操作。

我知道我可以这样做:

SELECT sql FROM SQLite_master WHERE type = 'index' AND tbl_name = 'MyTableName'

然后手动解析生成的SQL,但是我可以在某个地方找到一些元数据,这些元数据会给我一些东西吗?

 ------------------------------------
|   name    | column     | direction |
 ------------------------------------
| idx_a     | ColA       | ASC       |
 ------------------------------------
| idx_a_b   | ColB, ColB | DESC      |
 ------------------------------------

7 个答案:

答案 0 :(得分:11)

使用PRAGMA index_list(table-name);PRAGMA index_info(index-name); extensions

更新:PRAGMA schema.index_xinfo(index-name);将返回关键列的排序顺序。

答案 1 :(得分:8)

在where子句中添加您想要的任何条件。字段是:

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

Pastable select ...要包含索引的重要字段是" sql"。不会列出create table statment中定义的主键。

select type, name, tbl_name, sql
FROM sqlite_master
WHERE type='index'

答案 2 :(得分:2)

这就是你如何做到的:所有的索引元数据都可以通过'sqlite_master'表获得。请参阅SQLite常见问题解答的Q7:http://www.sqlite.org/faq.html#q7

答案 3 :(得分:1)

我找不到任何方法来简单地查询表元并得到我想要的indo,所以如果有人需要它,这就是我使用的。是的,正则表达式可能做得更干净,但你知道这句格言,如果Regex可以解决问题,那么现在你有两个问题。

public class SqlIndexInfo
{
    public string IndexName { get; set; }
    public string TableName { get; set; }
    public string[] Fields { get; set; }
    public bool IsAscending { get; set; }

    public bool IsComposite
    {
        get { return Fields.Length > 1; }
    }
}

public static class Extensions
{
    public static SqlIndexInfo ParseToIndexInfo(this string sql)
    {
        sql = sql.Trim();
        var info = new SqlIndexInfo();

        var i = sql.IndexOf("CREATE INDEX", 0, StringComparison.InvariantCultureIgnoreCase);
        if (i < 0) throw new ArgumentException("String is not valid CREATE INDEX SQL");
        var indexNameStart = i + "CREATE INDEX".Length + 1;

        i = sql.IndexOf(" ON ", 0, StringComparison.InvariantCultureIgnoreCase);
        if (i < 0) throw new ArgumentException("String is not valid CREATE INDEX SQL");
        var indexNameEnd = i;
        var tableNameStart = i + " ON ".Length;

        i = sql.IndexOf("(", 0, StringComparison.InvariantCultureIgnoreCase);
        if (i < 0) throw new ArgumentException("String is not valid CREATE INDEX SQL");
        var tableNameEnd = i;
        var fieldNamesStart = i + 1;

        i = sql.IndexOf(")", 0, StringComparison.InvariantCultureIgnoreCase);
        if (i < 0) throw new ArgumentException("String is not valid CREATE INDEX SQL");
        var fieldNamesEnd = i;
        var directionStart = i + 1;

        // TODO: strip brackets and/or single quotes?

        info.IndexName = sql.Substring(indexNameStart, indexNameEnd - indexNameStart).Trim();
        info.TableName = sql.Substring(tableNameStart, tableNameEnd - tableNameStart).Trim();
        info.Fields = (from f in sql.Substring(fieldNamesStart, fieldNamesEnd - fieldNamesStart).Split(',')
                      where !string.IsNullOrEmpty(f)
                      select f.Trim()).ToArray();

        if (directionStart >= sql.Length)
        {
            info.IsAscending = true;
        }
        else
        {
            info.IsAscending = sql.IndexOf("ASC", directionStart, StringComparison.InvariantCultureIgnoreCase) >= 0;
        }

        return info;
    }
}

答案 4 :(得分:0)

@neil简要提及SQLite Pragma statements Value of f for r= 0.000000 is f= 0.000000 f1= 0.000000 Value of f for r= 0.200000 is f= 0.199492 f1= 0.199492 Value of f for r= 0.400000 is f= 0.307038 f1= 0.307038 Value of f for r= 0.600000 is f= 0.193604 f1= 0.193604 Value of f for r= 0.800000 is f= 0.051949 f1= 0.051949 Value of f for r= 1.000000 is f= 0.000000 f1= 0.000000 Value of f for r= 1.200000 is f= 0.046058 f1= 0.046058 Value of f for r= 1.400000 is f= 0.166843 f1= 0.166843 Value of f for r= 1.600000 is f= 0.338256 f1= 0.338256 Value of f for r= 1.800000 is f= 0.542116 f1= 0.542116 Value of f for r= 2.000000 is f= 0.765977 f1= 0.765977 Value of f for r= 2.200000 is f= 1.001644 f1= 1.001644 Value of f for r= 2.400000 is f= 1.243810 f1= 1.243810 Value of f for r= 2.600000 is f= 1.489073 f1= 1.489073 Value of f for r= 2.800000 is f= 1.735278 f1= 1.735278 Value of f for r= 3.000000 is f= 1.981075 f1= 1.981075 Value of f for r= 3.200000 is f= 2.225642 f1= 2.225642 Value of f for r= 3.400000 is f= 2.468498 f1= 2.468498 Value of f for r= 3.600000 is f= 2.709387 f1= 2.709387 Value of f for r= 3.800000 is f= 2.948194 f1= 2.948194 Value of f for r= 4.000000 is f= 3.184898 f1= 3.184898 Value of f for r= 4.200000 is f= 3.419535 f1= 3.419535 Value of f for r= 4.400000 is f= 3.652177 f1= 3.652177 Value of f for r= 4.600000 is f= 3.882916 f1= 3.882916 Value of f for r= 4.800000 is f= 4.111856 f1= 4.111856 Value of f for r= 5.000000 is f= 4.339103 f1= 4.339103 PRAGMA INDEX_LIST['table_name']。根据文档,它们既可以作为SQLite命令存在,也可以在函数中使用(即PRAGMA INDEX_INFO['index_name']pragma_index_list(table_name)

为了更好地理解这一点,让我们看一下以下SQL:

pragma_index_info(index_name)

以下SQLite会话演示了如何查询索引:

CREATE TABLE Assets
(
    Asset_Id     INTEGER NOT NULL,
    Longitude    REAL    NOT NULL,
    Latitude     REAL    NOT NULL,
    Name         TEXT    NOT NULL,
    Installation REAL    NOT NULL,
    Constraint PK_Assets PRIMARY KEY (Asset_Id)
);
CREATE INDEX IX_Assets_Coordinate On Assets (Longitude, Latitude);
CREATE INDEX IX_Assets_Name On Assets (Name);

有趣的是,.mode csv sqlite> PRAGMA index_list('Assets'); seq,name,unique 0,IX_Assets_Name,0 1,IX_Assets_Coordinate,0 sqlite> PRAGMA index_info('IX_Assets_Name'); seqno,cid,name 0,3,Name sqlite> PRAGMA index_info('IX_Assets_Coordinate'); seqno,cid,name 0,1,Longitude 1,2,Latitude sqlite> 命令可以像PRAGMA语句一样使用,因此在SELECT中运行这些命令没有问题。

SQLite Pragma statements中,他们有一个有趣的示例SQL语句,用于枚举所有表的所有索引列:

C#

答案 5 :(得分:0)

SELECT 
    m.tbl_name as table_name,
    il.name as index_name,
    ii.name as column_name,
    CASE il.origin when 'pk' then 1 else 0 END as is_primary_key,
    CASE il.[unique] when 1 then 0 else 1 END as non_unique,
    il.[unique] as is_unique,
    il.partial,
    il.seq as sequence_in_index
FROM sqlite_master AS m,
    pragma_index_list(m.name) AS il,
    pragma_index_info(il.name) AS ii
WHERE 
    m.type = 'table'
    and m.tbl_name = 'YOUR TABLENAME HERE'
GROUP BY
    m.tbl_name,
    il.name,
    ii.name,
    il.origin,
    il.partial,
    il.seq
ORDER BY 1,6

答案 6 :(得分:0)

根据@Steve Lloyd 的回答进行优化,按 ii.seqno 排序

SELECT 
    m.tbl_name as table_name,
    il.name as index_name,
    ii.name as column_name,
    CASE il.origin when 'pk' then 1 else 0 END as is_primary_key,
    CASE il.[unique] when 1 then 0 else 1 END as non_unique,
    il.[unique] as is_unique,
    il.partial,
    il.seq as sequence_in_index,
    ii.seqno as sequence_in_column
FROM sqlite_master AS m,
    pragma_index_list(m.name) AS il,
    pragma_index_info(il.name) AS ii
WHERE 
    m.type = 'table'
    and m.tbl_name = 'YOUR TABLENAME HERE'
GROUP BY
    m.tbl_name,
    il.name,
    ii.name,
    il.origin,
    il.partial,
    il.seq
ORDER BY index_name,il.seq,ii.seqno