使用 C# 获取 SQLite 元数据
元数据是有关数据库中数据的信息。 SQLite 中的元数据包含有关表和列的信息,我们在其中存储数据。 受 SQL 语句影响的行数是元数据。 结果集中返回的行数和列数也属于元数据。
可以使用PRAGMA
命令获取 SQLite 中的元数据。 SQLite 对象可能具有属性,即元数据。 最后,我们还可以通过查询 SQLite 系统sqlite_master
表来获取特定的元数据。
using System;
using Mono.Data.Sqlite;
public class Example
{
static void Main()
{
string cs = "URI=file:test.db";
string nrows = null;
try {
Console.Write("Enter rows to fetch: ");
nrows = Console.ReadLine();
} catch (FormatException e)
{
Console.WriteLine(e.ToString());
}
using (SqliteConnection con = new SqliteConnection(cs))
{
con.Open();
using (SqliteCommand cmd = con.CreateCommand())
{
cmd.CommandText = "SELECT * FROM Cars LIMIT @Id";
cmd.Prepare();
cmd.Parameters.AddWithValue("@Id", Int32.Parse(nrows));
int cols = 0;
int rows = 0;
using (SqliteDataReader rdr = cmd.ExecuteReader())
{
cols = rdr.FieldCount;
rows = 0;
while (rdr.Read())
{
rows++;
}
Console.WriteLine("The query fetched {0} rows", rows);
Console.WriteLine("Each row has {0} cols", cols);
}
}
con.Close();
}
}
}
在上面的示例中,我们获取查询返回的行数和列数。
try {
Console.Write("Enter rows to fetch: ");
nrows = Console.ReadLine();
} catch (FormatException e)
{
Console.WriteLine(e.ToString());
}
该示例要求在命令行上的行数。
cmd.CommandText = "SELECT * FROM Cars LIMIT @Id";
cmd.Prepare();
cmd.Parameters.AddWithValue("@Id", Int32.Parse(nrows));
我们将选定的行限制为提供给程序的数目。
cols = rdr.FieldCount;
返回的列数可以很容易地从SqliteDataReader
对象的FieldCount
属性获得。
while (rdr.Read())
{
rows++;
}
我们计算结果集中的行数。
$ mono fields_rows.exe
Enter rows to fetch: 4
The query fetched 4 rows
Each row has 3 cols
输出。
列标题
接下来,我们将展示如何使用数据库表中的数据打印列标题。
using System;
using Mono.Data.Sqlite;
public class Example
{
static void Main()
{
string cs = "URI=file:test.db";
using (SqliteConnection con = new SqliteConnection(cs))
{
con.Open();
string stm = "SELECT * FROM Cars LIMIT 5";
using (SqliteCommand cmd = new SqliteCommand(stm, con))
{
using (SqliteDataReader rdr = cmd.ExecuteReader())
{
Console.WriteLine(String.Format("{0, -3} {1, -8} {2, 8}",
rdr.GetName(0), rdr.GetName(1), rdr.GetName(2)));
while (rdr.Read())
{
Console.WriteLine(String.Format("{0, -3} {1, -8} {2, 8}",
rdr.GetInt32(0), rdr.GetString(1), rdr.GetInt32(2)));
}
}
}
con.Close();
}
}
}
在此程序中,我们从Cars
表中选择 5 行及其列名。
using (SqliteDataReader rdr = cmd.ExecuteReader())
我们创建一个SqliteDataReader
对象。
Console.WriteLine(String.Format("{0, -3} {1, -8} {2, 8}",
rdr.GetName(0), rdr.GetName(1), rdr.GetName(2)));
我们使用阅读器的GetName()
方法获得列的名称。 String.Format()
方法用于格式化数据。
while (rdr.Read())
{
Console.WriteLine(String.Format("{0, -3} {1, -8} {2, 8}",
rdr.GetInt32(0), rdr.GetString(1), rdr.GetInt32(2)));
}
我们将 SQL 语句返回的数据打印到终端。
$ dmcs columns.cs -r:Mono.Data.Sqlite.dll
$ mono columns.exe
Id Name Price
1 Audi 52642
2 Mercedes 57127
3 Skoda 9000
4 Volvo 29000
5 Bentley 350000
该程序的输出。
受影响的行
在下面的示例中,我们将发现特定的 SQL 命令已进行了多少更改。
using System;
using Mono.Data.Sqlite;
public class Example
{
static void Main()
{
string cs = "Data Source=:memory:";
using (SqliteConnection con = new SqliteConnection(cs))
{
con.Open();
using (SqliteCommand cmd = new SqliteCommand(con))
{
cmd.CommandText = "CREATE TABLE Friends(Id INT, Name TEXT)";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Friends VALUES(1, 'Tom')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Friends VALUES(2, 'Jane')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Friends VALUES(3, 'Rebekka')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Friends VALUES(4, 'Lucy')";
cmd.ExecuteNonQuery();
cmd.CommandText = "INSERT INTO Friends VALUES(5, 'Robert')";
cmd.ExecuteNonQuery();
cmd.CommandText = "DELETE FROM Friends WHERE Id IN (3, 4, 5)";
int n = cmd.ExecuteNonQuery();
Console.WriteLine("The statement has affected {0} rows", n);
}
con.Close();
}
}
}
我们在内存中创建一个Friends
表。 在最后一个 SQL 命令中,我们删除三行。 ExecuteNonQuery()
方法返回受最后一个 SQL 命令影响的行数。
cmd.CommandText = "DELETE FROM Friends WHERE Id IN (3, 4, 5)";
在此 SQL 语句中,我们删除三行。
int n = cmd.ExecuteNonQuery();
我们找出上一条 SQL 语句完成的更改数量。
$ mono affected.exe
The statement has affected 3 rows
示例输出。
表架构
有GetSchemaTable()
方法,它返回有关每一列的元数据。 它返回许多值,其中包括列名,列大小,基表名或列是否唯一。
using System;
using System.Data;
using Mono.Data.Sqlite;
public class Example
{
static void Main()
{
string cs = "URI=file:test.db";
using(SqliteConnection con = new SqliteConnection(cs))
{
con.Open();
string stm = "SELECT * FROM Cars LIMIT 3";
using (SqliteCommand cmd = new SqliteCommand(stm, con))
{
using (SqliteDataReader rdr = cmd.ExecuteReader())
{
DataTable schemaTable = rdr.GetSchemaTable();
foreach (DataRow row in schemaTable.Rows)
{
foreach (DataColumn col in schemaTable.Columns)
Console.WriteLine(col.ColumnName + " = " + row[col]);
Console.WriteLine();
}
}
}
con.Close();
}
}
}
该示例打印有关表列的大量元数据。
DataTable schemaTable = rdr.GetSchemaTable();
我们得到架构表。
foreach (DataRow row in schemaTable.Rows)
{
foreach (DataColumn col in schemaTable.Columns)
Console.WriteLine(col.ColumnName + " = " + row[col]);
Console.WriteLine();
}
我们浏览保存元数据的模式表行,并将其打印到控制台。
$ dmcs schema.cs -r:Mono.Data.Sqlite.dll -r:System.Data.dll
$ mono schema.exe
ColumnName = Id
ColumnOrdinal = 0
ColumnSize = 8
NumericPrecision = 19
NumericScale = 0
IsUnique = True
IsKey = True
...
摘自示例输出。
表名
在与元数据有关的最后一个示例中,我们将列出test.db
数据库中的所有表。
using System;
using Mono.Data.Sqlite;
public class Example
{
static void Main()
{
string cs = "URI=file:test.db";
using (SqliteConnection con = new SqliteConnection(cs))
{
con.Open();
string stm = @"SELECT name FROM sqlite_master
WHERE type='table' ORDER BY name";
using (SqliteCommand cmd = new SqliteCommand(stm, con))
{
using (SqliteDataReader rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
Console.WriteLine(rdr.GetString(0));
}
}
}
con.Close();
}
}
}
该代码示例将所选数据库中的所有可用表打印到终端。
string stm = @"SELECT name FROM sqlite_master
WHERE type='table' ORDER BY name";
表名称是从sqlite_master
表中检索的。
$ mono tables.exe
Cars
Friends
Images
这些是我们系统上的表。
在 SQLite C# 教程的这一部分中,我们使用了数据库元数据。