改变 TABLE for ADO.NET sqlite for xamarin android
ALTER TABLE for ADO.NET sqlite for xamarin android
我需要在我的 sqlite table 中添加新列。我已经读过 ALTER TABLE 和 PRAGMA table_info,但作为独立(自学)开发人员,我不知道如何实现它。这是我的数据库中的代码 class(我从 xamarin 的 Tasky 示例应用程序中获得):
public class YesDatabase
{
static object locker = new object ();
public SqliteConnection connection;
public string path;
public YesDatabase (string dbPath)
{
var output = "";
path = dbPath;
// create the tables
bool exists = File.Exists (dbPath);
if (!exists)
{
connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
var ccommandsc = new[] {
"CREATE TABLE IF NOT EXISTS [Citems] (_id INTEGER PRIMARY KEY ASC, Cname NTEXT, Cnotes NTEXT, Ccat NTEXT);"
};
foreach (var commandc in ccommandsc) {
using (var d = connection.CreateCommand ()) {
d.CommandText = commandc;
var j = d.ExecuteNonQuery ();
}
}
//for first time users
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
} else
{
// db already exists, add column
connection = new SqliteConnection("Data Source=" + dbPath);
connection.Open();
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
}
Console.WriteLine (output);
}
Contact FromReaderc (SqliteDataReader r) {
var c = new Contact ();
c.ID = Convert.ToInt32 (r ["_id"]);
c.Cname = r ["Cname"].ToString ();
c.Cnotes = r ["Cnotes"].ToString ();
c.Ccat = r ["Ccat"].ToString ();
c.Cnumber = r ["Cnumber"].ToString ();
return c;
}
你会使用
ALTER TABLE your_table ADD COLUMN you_column_definition
所以可以
ALTER TABLE [Citems] ADD COLUMN Cother REAL NOT NULL DEFAULT 10.12345
- [引用] 替换
your_table
- Cother 是列名
- 列类型将为 REAL
- 约束不为空。
- 该列的默认值为 10.12345
调用上面的(当然修改以适应)将代替 // already exists, do nothing.
执行
请注意,可以添加的列有限制:-
The ADD COLUMN syntax is used to add a new column to an existing
table. The new column is always appended to the end of the list of
existing columns. The column-def rule defines the characteristics of
the new column. The new column may take any of the forms permissible
in a CREATE TABLE statement, with the following restrictions:
- The column may not have a PRIMARY KEY or UNIQUE constraint.
- The column
may not have a default value of CURRENT_TIME, CURRENT_DATE,
CURRENT_TIMESTAMP, or an expression in parentheses.
- If a NOT NULL
constraint is specified, then the column must have a default value
other than NULL.
- If foreign key constraints are enabled and a column
with a REFERENCES clause is added, the column must have a default
value of NULL.
Note also that when adding a CHECK constraint, the
CHECK constraint is not tested against preexisting rows of the table.
This can result in a table that contains data that is in violation of
the CHECK constraint. Future versions of SQLite might change to
validate CHECK constraints as they are added.
SQL As Understood By SQLite - ALTER TABLE
I have read that the command PRAGMA table_info is needed to prevent
errors in adding that column again when that app is re-opened
这不是真的,您可以通过查询 sqlite_master table 来检查该列是否存在,其中包括一个名为 的列sql 即创建 table.
所需的 SQL
例如(假设要检查的列是 Cother )然后:-
SELECT instr(sql,' Cother ') > 0 AS result FROM sqlite_master WHERE name = 'mytable';
如果 table 存在, 将 return 1 行,如果该列不存在,则为 0,如果该列存在,则为 1。
如果SQLite版本低于3.7.15,因此instr核心功能不存在
那么可以使用下面的:-
SELECT 1 FROM sqlite_master WHERE name = 'mytable' AND sql LIKE '% Cother %'
如果该列存在,这将 return 一行;如果该列不存在,则没有行。
您将使用 PRAGMA table_info([Citems])
到 return 行和列 :-
- cid
- 姓名
- 类型
- 非空
- dflt_value
- pk
然后您必须遍历行检查 name 列是否包含该列,因此使用起来有点复杂。
and the part where ALTER TABLE command can be written
如前所述,如果数据库存在,您将执行此操作,因此要替换行 :-
// already exists, do nothing.
public class YesDatabase
{
static object locker = new object ();
public SqliteConnection connection;
public string path;
/// <summary>
/// Initializes a new instance of the <see cref="Tasky.DL.TaskDatabase"/> TaskDatabase.
/// if the database doesn't exist, it will create the database and all the tables.
/// </summary>
///
public YesDatabase (string dbPath)
{
var output = "";
path = dbPath;
// create the tables
bool exists = File.Exists (dbPath);
if (!exists) {
connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
var ccommandsc = new[] {
"CREATE TABLE IF NOT EXISTS [Citems] (_id INTEGER PRIMARY KEY ASC, Cname NTEXT, Cnotes NTEXT, Ccat NTEXT);"
};
foreach (var commandc in ccommandsc) {
using (var d = connection.CreateCommand ()) {
d.CommandText = commandc;
var j = d.ExecuteNonQuery ();
}
}
//new column.
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
} else {
//
connection = new SqliteConnection("Data Source=" + dbPath);
connection.Open();
//
if (!CheckIfCnumberExists())
{
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
}
}
Console.WriteLine (output);
}
private bool CheckIfCnumberExists()
{
using (var conn = new SqliteConnection("Data Source=" + path))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "PRAGMA table_info([Citems])";
var reader = cmd.ExecuteReader();
int nameIndex = reader.GetOrdinal("Name");
while (reader.Read())
{
if (reader.GetString(nameIndex).Equals("Cnumber"))
{
//conn.close();
return true;
}
}
conn.Close();
}
return false;
}
我需要在我的 sqlite table 中添加新列。我已经读过 ALTER TABLE 和 PRAGMA table_info,但作为独立(自学)开发人员,我不知道如何实现它。这是我的数据库中的代码 class(我从 xamarin 的 Tasky 示例应用程序中获得):
public class YesDatabase
{ static object locker = new object ();
public SqliteConnection connection;
public string path;
public YesDatabase (string dbPath)
{
var output = "";
path = dbPath;
// create the tables
bool exists = File.Exists (dbPath);
if (!exists)
{
connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
var ccommandsc = new[] {
"CREATE TABLE IF NOT EXISTS [Citems] (_id INTEGER PRIMARY KEY ASC, Cname NTEXT, Cnotes NTEXT, Ccat NTEXT);"
};
foreach (var commandc in ccommandsc) {
using (var d = connection.CreateCommand ()) {
d.CommandText = commandc;
var j = d.ExecuteNonQuery ();
}
}
//for first time users
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
} else
{
// db already exists, add column
connection = new SqliteConnection("Data Source=" + dbPath);
connection.Open();
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
}
Console.WriteLine (output);
}
Contact FromReaderc (SqliteDataReader r) {
var c = new Contact ();
c.ID = Convert.ToInt32 (r ["_id"]);
c.Cname = r ["Cname"].ToString ();
c.Cnotes = r ["Cnotes"].ToString ();
c.Ccat = r ["Ccat"].ToString ();
c.Cnumber = r ["Cnumber"].ToString ();
return c;
}
你会使用
ALTER TABLE your_table ADD COLUMN you_column_definition
所以可以
ALTER TABLE [Citems] ADD COLUMN Cother REAL NOT NULL DEFAULT 10.12345
- [引用] 替换
your_table
- Cother 是列名
- 列类型将为 REAL
- 约束不为空。
- 该列的默认值为 10.12345
调用上面的(当然修改以适应)将代替 // already exists, do nothing.
请注意,可以添加的列有限制:-
The ADD COLUMN syntax is used to add a new column to an existing table. The new column is always appended to the end of the list of existing columns. The column-def rule defines the characteristics of the new column. The new column may take any of the forms permissible in a CREATE TABLE statement, with the following restrictions:
- The column may not have a PRIMARY KEY or UNIQUE constraint.
- The column may not have a default value of CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP, or an expression in parentheses.
- If a NOT NULL constraint is specified, then the column must have a default value other than NULL.
- If foreign key constraints are enabled and a column with a REFERENCES clause is added, the column must have a default value of NULL.
Note also that when adding a CHECK constraint, the CHECK constraint is not tested against preexisting rows of the table. This can result in a table that contains data that is in violation of the CHECK constraint. Future versions of SQLite might change to validate CHECK constraints as they are added.
SQL As Understood By SQLite - ALTER TABLE
I have read that the command PRAGMA table_info is needed to prevent errors in adding that column again when that app is re-opened
这不是真的,您可以通过查询 sqlite_master table 来检查该列是否存在,其中包括一个名为 的列sql 即创建 table.
所需的 SQL例如(假设要检查的列是 Cother )然后:-
SELECT instr(sql,' Cother ') > 0 AS result FROM sqlite_master WHERE name = 'mytable';
如果 table 存在,将 return 1 行,如果该列不存在,则为 0,如果该列存在,则为 1。
如果SQLite版本低于3.7.15,因此instr核心功能不存在
那么可以使用下面的:-
SELECT 1 FROM sqlite_master WHERE name = 'mytable' AND sql LIKE '% Cother %'
如果该列存在,这将 return 一行;如果该列不存在,则没有行。
您将使用 PRAGMA table_info([Citems])
到 return 行和列 :-
- cid
- 姓名
- 类型
- 非空
- dflt_value
- pk
然后您必须遍历行检查 name 列是否包含该列,因此使用起来有点复杂。
and the part where ALTER TABLE command can be written
如前所述,如果数据库存在,您将执行此操作,因此要替换行 :-
// already exists, do nothing.
public class YesDatabase
{
static object locker = new object ();
public SqliteConnection connection;
public string path;
/// <summary>
/// Initializes a new instance of the <see cref="Tasky.DL.TaskDatabase"/> TaskDatabase.
/// if the database doesn't exist, it will create the database and all the tables.
/// </summary>
///
public YesDatabase (string dbPath)
{
var output = "";
path = dbPath;
// create the tables
bool exists = File.Exists (dbPath);
if (!exists) {
connection = new SqliteConnection ("Data Source=" + dbPath);
connection.Open ();
var ccommandsc = new[] {
"CREATE TABLE IF NOT EXISTS [Citems] (_id INTEGER PRIMARY KEY ASC, Cname NTEXT, Cnotes NTEXT, Ccat NTEXT);"
};
foreach (var commandc in ccommandsc) {
using (var d = connection.CreateCommand ()) {
d.CommandText = commandc;
var j = d.ExecuteNonQuery ();
}
}
//new column.
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
} else {
//
connection = new SqliteConnection("Data Source=" + dbPath);
connection.Open();
//
if (!CheckIfCnumberExists())
{
using (var f = connection.CreateCommand())
{
f.CommandText = "ALTER TABLE [Citems] ADD COLUMN Cnumber NTEXT";
var l = f.ExecuteNonQuery();
}
}
}
Console.WriteLine (output);
}
private bool CheckIfCnumberExists()
{
using (var conn = new SqliteConnection("Data Source=" + path))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "PRAGMA table_info([Citems])";
var reader = cmd.ExecuteReader();
int nameIndex = reader.GetOrdinal("Name");
while (reader.Read())
{
if (reader.GetString(nameIndex).Equals("Cnumber"))
{
//conn.close();
return true;
}
}
conn.Close();
}
return false;
}