给定一个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 | ------------------------------------
答案 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