我希望有人能够帮助解决我的SQLite数据库问题。
我在使用C#查询SQLite数据库时收到ConstraintException
。完整的异常消息是“Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.
”我最初使用访问权限构建了这个数据库,但是出于各种原因我不得不使用SQLite重新创建它。
为了给出一些背景知识 - 这是一个简单的状态调度程序。每个Status
都有关联的Account
和Schedule
。我意识到Statuses
和Schedule
是一个1:1的关系,并且可以在同一个表中但是为了让程序进一步发展我将它们分成两个表。
请参阅下面的表格脚本的缩减版本(这足以重现问题)。
PRAGMA foreign_keys = ON;
CREATE TABLE Accounts
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
Name char(100));
CREATE TABLE Statuses
(ID INTEGER PRIMARY KEY AUTOINCREMENT,
AccountId INTEGER REFERENCES Accounts(ID) ON DELETE CASCADE,
Text char(140));
CREATE TABLE Schedule
(ID INTEGER PRIMARY KEY REFERENCES Statuses(ID) ON DELETE CASCADE,
StartDate char(255),
Frequency INT);
在我创建两个Statues
并将它们关联到同一个Account
之前,我没有遇到任何问题。
Accounts
ID Name
1 Fred Blogs
Statuses
ID AccountId Text
1 1 “Some text”
2 1 “Some more text”
Schedule
ID StartDate Frequency
1 16/02/2011 1
2 16/02/2011 1
我正在使用的抛出异常的select语句是:
SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
如果我运行相同的查询,但删除了“Accounts.Id
”列,则查询工作正常。
请参阅下面的我正在使用的C#代码,但我不认为这是问题
public DataTable Query(string commandText)
{
SQLiteConnection sqliteCon = new SQLiteConnection(ConnectionString);
SQLiteCommand sqliteCom = new SQLiteCommand(commandText, sqliteCon);
DataTable sqliteResult = new DataTable("Query Result");
try
{
sqliteCon.Open();
sqliteResult.Load(sqliteCom.ExecuteReader());
}
catch (Exception)
{
throw;
}
finally
{
sqliteCon.Close();
}
return sqliteResult;
}
任何帮助将不胜感激。感谢。
答案 0 :(得分:2)
由于“状态”表和“计划”表中的ID列而发生错误。如果它们不重要,请删除两个表中的列。
答案 1 :(得分:2)
我找到了解决这个问题的方法。如果我从Schedule表而不是Accounts表中选择AccountId,则不会抛出异常。似乎我无法运行包含两个唯一主键列的SELECT语句。
所以而不是
SELECT Statuses.Id, Statuses.Text, Accounts.Id, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
我跑
SELECT Statuses.Id, Statuses.Text, Statuses.AccountId, Accounts.Name, Schedule.StartDate, Schedule.Frequency
FROM [Statuses], [Accounts], [Schedule]
WHERE Statuses.AccountId = Accounts.Id AND Statuses.Id = Schedule.Id
答案 2 :(得分:0)
我通过首先读取模式来解决问题,然后清除数据表的约束,然后再次读取数据。 像这样:
DataSet DS = new DataSet();
mytable = new DataTable();
DS.Tables.Add(mytable);
DS.EnforceConstraints = false;
SQLiteCommand command = DBconnection.CreateCommand();
command.CommandText = "select * from V_FullView";
SQLiteDataReader reader = command.ExecuteReader(CommandBehavior.SchemaOnly);
mytable.Load(reader);
mytable.Constraints.Clear();
reader = command.ExecuteReader();
mytable.Load(reader);
reader.Close();
我的V_FullView是4个不同表合并的视图。似乎约束是第一个合并表的约束(名称在该表上是唯一的,但在视图中复制了多次)