Duplicate value exception while inserting into an autoincremental-PK table
I recently experienced a SqlCeException
: "A duplicate value cannot be inserted into a unique index" while inserting a record in a table (SqlCE 3.5).
It seems the INSERT statement violates the primary key constraint. However, on the relevant table, the PK has been defined as an autoincrementing identity:
[ID] int identity(1,1) NOT NULL,
The exception is not systematical: it happens once in a while.
What could be the cause of this exception?
Doesn't theidentity(1,1)
guarantee a unique ID for each INSERT, does it?
Could this be a SqlCE bug? If so, how could it be circumvented?
Here is the Exception trace (it explicitly refers to the PK_ID constraint):
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 ...
Table definition is:
CREATE TABLE [HistoricalData] (
[ID] int identity(1,1) NOT NULL,
1675855251 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, 1675855251 ASC);
CREATE INDEX [IDX_Timestamp]
ON [HistoricalData] (1675855251 ASC);
The INSERT is performed via a SqlCeCommand. Here is the code (C#):
_insertRecordCo开发者_开发百科mmand =
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();
I left out how parameters are filled. Nevertheless, there is no [ID] (the primary key) parameter.
精彩评论