我最近遇到了SqlCeException
:在表中插入记录时,“重复值无法插入到唯一索引中”(SqlCE 3.5)。
似乎INSERT语句违反了主键约束。但是,在相关表格中,PK已被定义为自动增量标识:
[ID] int identity(1,1) NOT NULL,
例外不是系统性的:它偶尔会发生。
这种例外可能是什么原因?
identity(1,1)
不保证每个INSERT的唯一ID吗?是吗?
这可能是一个SqlCE错误吗?如果是这样,怎么可能被规避呢?
这是异常跟踪(它明确引用PK_ID约束):
System.Data.SqlServerCe.SqlCeException: A duplicate value cannot be inserted into a unique index. [ Table name = HistoricalData,Constraint name = PK_ID ]
at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText(IntPtr& pCursor, Boolean& isBaseTableCursor)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options)
at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery()
at Invensys.Compact.Persistence.SqlCe.PlantData.SaveHistoricalRecord(HistoricalRecord record)
at ...
表定义是:
CREATE TABLE [HistoricalData] (
[ID] int identity(1,1) NOT NULL,
[Timestamp] datetime NOT NULL,
[Type] smallint NOT NULL,
[IDLastAll] int,
[IDRef] int NOT NULL,
[BinaryLength] smallint NOT NULL,
[Data00] varbinary(500),
[Data01] varbinary(500),
[Data02] varbinary(500),
[Data03] varbinary(500),
[Data04] varbinary(500),
[Data05] varbinary(500),
[Data06] varbinary(500),
[Data07] varbinary(500),
[Data08] varbinary(500),
[Data09] varbinary(500));
-- Create Primary Key Constraints
ALTER TABLE [HistoricalData] ADD CONSTRAINT [PK_ID]
PRIMARY KEY ([ID]);
-- Create Indexes
CREATE INDEX [IDX_Type_Timestamp]
ON [HistoricalData] ([Type] ASC, [Timestamp] ASC);
CREATE INDEX [IDX_Timestamp]
ON [HistoricalData] ([Timestamp] ASC);
INSERT通过SqlCeCommand执行。这是代码(C#):
_insertRecordCommand =
new SqlCeCommand
{
Connection = _connection,
CommandType = CommandType.Text,
CommandText = HISTORICAL_DATA_INSERT
};
_insertRecordCommand.Parameters.Add("@Timestamp", SqlDbType.DateTime);
_insertRecordCommand.Parameters.Add("@Type", SqlDbType.SmallInt);
_insertRecordCommand.Parameters.Add("@IDLastAll", SqlDbType.Int);
_insertRecordCommand.Parameters.Add("@IDRef", SqlDbType.Int);
_insertRecordCommand.Parameters.Add("@BinaryLength", SqlDbType.Int);
for (var i = 0; i < DATA_BLOCK_NUMBER; i++)
{
_insertRecordCommand.Parameters.Add(DATAPARAMETERNAMES[i], SqlDbType.VarBinary, DATA_BLOCK_SIZE);
}
_insertRecordCommand.Prepare();
// Here the parameters are filled.
_insertRecordCommand.ExecuteNonQuery();
我遗漏了如何填充参数。然而,没有[ID](主键)参数。