2012-11-16 138 views
3

给定一个SQLite数据库,我需要获取给定表中列的索引列表以及排序顺序。我需要从代码(C#,尽管这不重要)做到这一点,所以我真正需要的是一个SQL语句,如果存在,就这样做。如何获取给定表的索引列的列表

我知道我能做到这一点:

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

,然后手动解析生成的SQL,但有一些元数据的地方,我就可以查询会给我东西沿着这些路线?

​​

回答

1

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

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; 
    } 
} 
+0

真是痛苦!感谢分享。 –

1

这实际上是如何做到的:所有的索引元数据都可以通过'sqlite_master'表获得。参见SQLite FAQ的Q7:http://www.sqlite.org/faq.html#q7

+0

我不确定为什么有人低估了我,但让我重申一遍:sqlite_master表是通过SQL访问这些数据的本地方式。没有其他的本地机制。 –

+0

但sqlite_master表不包含索引名称,列和排序方向(在SQL语句之外)。我试图避免解析。 – ctacke

5

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

+0

我看到我可以通过获取索引列表来获取列,然后获取列的信息,但排序顺序又如何呢?如果是ASC或DESC,我不会看到任何内容。 – ctacke

+0

@ctacke是的,它似乎缺少排序顺序。叹。 – Neil

5

在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' 
相关问题