Я использую OleDbDataAdapter и OleDbCommandBuilder, чтобы заполнить объект DataSet содержимым базы данных, а затем обновить базу данных в соответствии с изменениями, внесенными мной в DataSet. Проблема в том, что я получаю исключение: «Нарушение параллелизма: UpdateCommand затронул 0 ожидаемых 1 записей». Я нашел объяснение этой ошибки:Получить команды SQL OleDbCommandBuilder
Because a record could have been modified after it was returned from the SELECT statement, but before the UPDATE or DELETE statement is issued, the automatically generated UPDATE or DELETE statement contains a WHERE clause, specifying that a row is only updated if it contains all original values and has not been deleted from the data source. Where an automatically generated update attempts to update a row that has been deleted or that does not contain the original values found in the DataSet, the command does not affect any records, and a DBConcurrencyException is thrown.
Это означает, что автогенерируемая команда UPDATE влияет 0 строк в базе данных. Я работаю с базой данных парадокса (db-file), и никто не меняет ее, кроме меня. Я предполагаю, что моя программа несколько раз меняет одну и ту же строку. Я хотел отлаживать свою программу, выполняя все сгенерированные запросы вручную и обнаруживая, что какой-то не влияет на какую-либо строку (потому что на самом деле я уверен, что все изменения производятся только один раз, а ошибка где-то еще))). Можно ли запускать автоматически созданные команды вручную?
Мой код является слишком большим и сложным, чтобы разместить его здесь, но в целом она работает, как это (я сделал рабочий проект и взял его оттуда)
using System;
using System.Data;
using System.Windows.Forms;
using System.Data.OleDb;
namespace OleDBCommandBuilder
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string cs = @"Provider=Microsoft.Jet.OLEDB.4.0;";
cs += @"Data Source=C:\FOLDER\1\SPR_KMZ\;";
cs += @"Extended Properties=Paradox 5.x;";
OleDbConnection Connection = new OleDbConnection();
Connection.ConnectionString = cs;
try
{ Connection.Open(); }
catch (Exception ex)
{ MessageBox.Show("Error openning database! " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Environment.Exit(0); }
string SQLQuery = "SELECT * FROM SPR_KMZ WHERE REZ<>0";
DataSet SPR_KMZ = new DataSet();
OleDbDataAdapter DataAdapter = new OleDbDataAdapter();
DataAdapter.SelectCommand = new OleDbCommand(SQLQuery, Connection);
OleDbCommandBuilder builder = new OleDbCommandBuilder(DataAdapter);
try
{
DataAdapter.Fill(SPR_KMZ);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(String.Format("Error \n{0}\n{1}", ex.Message, SQLQuery));
Environment.Exit(0);
}
DataRow[] SPR_KMZ_rows = SPR_KMZ.Tables[0].Select("Fkmz=10000912 AND REZ=1");
foreach (DataRow SPR_KMZ_row in SPR_KMZ_rows)
{
SPR_KMZ_row["DN"] = Convert.ToDateTime("30.12.1899");//26.12.2008
SPR_KMZ_row["Price"] = Convert.ToDouble(0);//168,92
}
DataAdapter.Update(SPR_KMZ);
System.Windows.Forms.MessageBox.Show("Success!");
Environment.Exit(0);
}
}
}
P.S. Раньше он обновлял базу данных без исключения параллелизма, но после большого количества изменений (я прокомментировал строку «DataAdapter.Update (SPR_KMZ)», «долгое время для отладки, поэтому я не знаю, когда именно эта ошибка начиналась с бросок)
PSS нет вставки или удаления в моем коде, только обновления ...
< <UPDATE> >
я нашел то, что была проблема: если поле «DN» имеет значение NULL, то после его изменения, автоматически сгенерированное заявление UPDATE ничего не влияет, очевидно, потому что «DN» содержится в первичном ключе, а построитель команд не ожидал, что для поля первичного ключа будут иметь значения NULL (кто когда-либо будет))), неудивительно, что этот движок называется «Парадокс»)))
вот почему в
CommandBuilder.GetUpdateCommand().CommandText
в раздел, где для поля "DN" был этот вид узора:
... WHERE ((REZ = ?) AND (DN = ?) AND ...
в то время как обнуляемых поля описываются следующим образом:
... AND ((? = 1 AND Price IS NULL) OR (Price = ?)) AND ((? = 1 AND Nmed IS NULL) OR (Nmed = ?)) AND ...
P.S.S.S. Эй, я могу попытаться установить UpdateCommand вручную, чтобы исправить это!))
Есть ли какая-нибудь возможность включить код, который вы используете? –
Поиск отсутствующей инструкции вставки или инструкции удаления. Можно ли уменьшить вашу проблему, уменьшив количество мутаций DataSet? –