Gerhard_Louis Ответов: 1

Как предотвратить нарушение первичного ключа при обновлении базы данных access


Я могу успешно импортировать две таблицы из базы данных paradox и добавить данные в одну таблицу доступа.Из таблицы one paradox я использую поле ID, поскольку оно является первичным ключом для привязки часов к датам, и я сделал свой первичный ключ доступа равным полю ID таблицы. Clockd.ID.

Как добавить таблицу доступа при обновлении из базы данных paradox добавив только новые записи
Я немного озадачен этим
Вот как далеко я зашел.Любые рекомендации будут оценены по достоинству

private void mtrBtnLoad_Click(object sender, EventArgs e)
{
   string connStringSource = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\\Program Files\\Supertime\\db;Extended Properties=Paradox 5.x;";

   string connStringDest = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\Yellow\\Documents\\paradoxExport.accdb; Persist Security Info=False;";

   OleDbConnection connSource = new OleDbConnection(connStringSource);
   OleDbConnection connDest = new OleDbConnection(connStringDest);

   OleDbCommand cmdSelect = new OleDbCommand(@"Select Clockd.ID, Empmas.EmpNo, Empmas.Name, Clockd.DateTime, Calc0R1, Calc1R1, Calc2R1, Calc3R1, Calc4R1, TotalHours, Target0R1 FROM Empmas INNER JOIN Clockd ON Empmas.EmpNo=Clockd.Empno", connSource);

   OleDbCommand cmdIns = new OleDbCommand(@"INSERT INTO Clockd ([ID], EmpNo, [Name], [DateTime], Calc0R1, Calc1R1, Calc2R1, Calc3R1, Calc4R1, TotalHours, Target0R1) VALUES (@ID, @EmpNo, @Name, @DateTime, @Calc0R1, @Calc1R1, @Calc2R1, @Calc3R1, @Calc4R1, @TotalHours, @Target0R1)", connDest);

   cmdIns.Parameters.Add(new OleDbParameter("@ID", OleDbType.VarChar, 11,"ID"));
   cmdIns.Parameters.Add(new OleDbParameter("@EmpNo", OleDbType.VarChar, 11, "EmpNo"));
   cmdIns.Parameters.Add(new OleDbParameter("@Name", OleDbType.VarChar, 11, "Name"));
   cmdIns.Parameters.Add(new OleDbParameter("@DateTime", OleDbType.Date, 4, "DateTime"));
   cmdIns.Parameters.Add(new OleDbParameter("@Calc0R1", OleDbType.Integer, 8, "Calc0R1"));
   cmdIns.Parameters.Add(new OleDbParameter("@Calc1R1", OleDbType.Integer,8, "Calc1R1"));
   cmdIns.Parameters.Add(new OleDbParameter("@Calc2R1", OleDbType.Integer, 8, "Calc2R1"));
   cmdIns.Parameters.Add(new OleDbParameter("@Calc3R1", OleDbType.Integer, 8, "Calc3R1"));
   cmdIns.Parameters.Add(new OleDbParameter("@Calc4R1", OleDbType.Integer, 8, "Calc4R1"));
   cmdIns.Parameters.Add(new OleDbParameter("@TotalHours", OleDbType.Integer, 4, "TotalHours"));
   cmdIns.Parameters.Add(new OleDbParameter("@Target0R1", OleDbType.Integer, 4, "Target0R1"));

   OleDbDataAdapter da = new OleDbDataAdapter(connStringDest,connStringDest); 
   da.AcceptChangesDuringFill = false;
   da.SelectCommand = cmdSelect;
   da.InsertCommand = cmdIns;

   System.Data.DataSet ds = new System.Data.DataSet();
   da.Fill(ds);
   da.Update(ds);
   DataTable dt = new DataTable();
   BindingSource bs = new BindingSource();
   bs.DataSource = dt;
   dvg1.DataSource = bs;
}

1 Ответов

Рейтинг:
12

Member 11428137

Вам нужно будет получить запрос insert, чтобы проверить, существует ли идентификатор уже перед вставкой записи.
К сожалению, чтобы иметь возможность поместить предложение WHERE в запрос INSERT в Access, требуется использовать запрос INSERT INTO SELECT.
Это, конечно, означает, что вам нужно иметь таблицу для выбора, в то время как вы хотите просто дать ей некоторые значения для вставки.
Это делает запрос немного длиннее и не совсем таким ясным, как это было бы с чем-то вроде SQL Server, но все равно должно быть возможно.

Попробуйте выполнить этот запрос вставки:

OleDbCommand cmdIns = new OleDbCommand(@"INSERT INTO Clockd ([ID], EmpNo, [Name], [DateTime], Calc0R1, Calc1R1, Calc2R1, Calc3R1, Calc4R1, TotalHours, Target0R1) SELECT TOP 1 @ID, @EmpNo, @Name, @DateTime, @Calc0R1, @Calc1R1, @Calc2R1, @Calc3R1, @Calc4R1, @TotalHours, @Target0R1 FROM Clockd WHERE NOT EXISTS (SELECT [ID] FROM Clockd WHERE [ID]=@ID)", connDest);


Он делает выбор (ограниченный 1 строкой), который вернет все параметры, но только в том случае, если идентификатор еще не существует в таблице.


Gerhard_Louis

Привет, спасибо.Это работает.Я добавил ручную метку времени в базу данных paradox и отметил уникальный идентификатор, который она сгенерировала, а затем убедился, что в моей таблице доступа нет записи с этим уникальным идентификатором, и обновил ее.И снова обновил его, и я не получал того же нарушения первичного ключа.Хотя обновление записей 700 сотрудников занимает целую вечность

Member 11428137

Это приятно слышать. Да, к сожалению, он, вероятно, довольно медленный, так как по необходимости делает только один ряд за раз. Кроме того, я не думаю, что он способен оптимизировать его, пакуя команды. Это обычная вещь, что вы запускаете этот импорт, или более разовая вещь/время от времени?

Gerhard_Louis

Это только для одного клиента.К сожалению, мы застряли с использованием базы данных paradox, пока не перейдем на Sql