Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取OleDbCommandBuilder生成的SQL命令_C#_Oledb_Dbase - Fatal编程技术网

C# 获取OleDbCommandBuilder生成的SQL命令

C# 获取OleDbCommandBuilder生成的SQL命令,c#,oledb,dbase,C#,Oledb,Dbase,我使用OleDbDataAdapter和OleDbCommandBuilder用数据库内容填充数据集对象,然后根据我在数据集中所做的更改更新数据库。问题是我得到了异常:并发冲突:UpdateCommand影响了预期的1条记录中的0条。我找到了此错误的解释: 因为记录从返回后可能已被修改 SELECT语句,但在UPDATE或DELETE语句 发出时,自动生成的UPDATE或DELETE语句 包含WHERE子句,指定仅当行 包含所有原始值,尚未从数据中删除 来源自动生成的更新尝试更新 已删除或不包含

我使用OleDbDataAdapter和OleDbCommandBuilder用数据库内容填充数据集对象,然后根据我在数据集中所做的更改更新数据库。问题是我得到了异常:并发冲突:UpdateCommand影响了预期的1条记录中的0条。我找到了此错误的解释:

因为记录从返回后可能已被修改 SELECT语句,但在UPDATE或DELETE语句 发出时,自动生成的UPDATE或DELETE语句 包含WHERE子句,指定仅当行 包含所有原始值,尚未从数据中删除 来源自动生成的更新尝试更新 已删除或不包含原始值的行 在数据集中找到,该命令不影响任何记录,并且 抛出DBConcurrencyException

这意味着自动生成的UPDATE命令影响了数据库中的0行。我使用paradoxdb文件数据库,除了我之外,没有人更改它。我猜我的程序在某个地方更改了同一行两次。我想通过手动执行所有生成的查询来调试我的程序,并找到哪一个查询不会影响任何行,因为实际上我非常确定所有更改只进行了一次,而错误在其他地方。是否可以手动运行自动生成的命令

我的代码太大太复杂了,无法在这里发布,但一般来说,它是这样工作的。我做了一个工作项目,然后从那里开始

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);
        }
    }
}
DN字段的where子句中存在这种模式:

... WHERE ((REZ = ?) AND (DN = ?) AND ...
可为空的字段描述如下:

... AND ((? = 1 AND Price IS NULL) OR (Price = ?)) AND ((? = 1 AND Nmed IS NULL) OR (Nmed = ?)) AND ...

嘿,我可以试着手动设置UpdateCommand来解决这个问题

以下是我如何手动设置UpdateCommand,甚至为每个正在执行的更新命令获取SQL代码的方法!或多或少这在调试时非常有用-我可以看到DataAdapter.UpdateDBDataSet命令执行期间sql查询失败的地方

public void Update(DataSet DBDataSet)
{
    DataAdapter.RowUpdating += before_update;
    DataAdapter.Update(DBDataSet);
}

public void before_update(object sender, EventArgs e)
{
    //Convert EventArgs to OleDbRowUpdatingEventArgs to be able to use OleDbCommand property
    System.Data.OleDb.OleDbRowUpdatingEventArgs oledb_e = (System.Data.OleDb.OleDbRowUpdatingEventArgs) e;

    //Get query template
    string cmd_txt = oledb_e.Command.CommandText;

    //Modify query template here to fix it
    //cmd_txt = cmd_txt.Replace("table_name", "\"table_name\"");

    //fill tamplate with values
    string cmd_txt_filled = cmd_txt;
    foreach(System.Data.OleDb.OleDbParameter par in oledb_e.Command.Parameters)
    {
        string par_type = par.DbType.ToString();
        string string_to_replace_with = "";

        if (par.Value.GetType().Name == "DBNull")
        {
            string_to_replace_with = "NULL";
        }
        else
        {
            if (par_type == "Int32")
            {
                par.Size = 4;
                string_to_replace_with=Convert.ToInt32(par.Value).ToString();
            }
            else if (par_type == "Double")
            {
                par.Size = 8;
                string_to_replace_with=Convert.ToDouble(par.Value).ToString().Replace(",",".");
            }
            else if (par_type == "DateTime")
            {
                par.Size = 8;
                /* In Paradox SQL queries you can't just specify the date as a string,
                 * it will result in incompatible types, you have to count the days
                 * between 30.12.1899 and the required date and specify that number
                 */
                string_to_replace_with = DateToParadoxDays(Convert.ToDateTime(par.Value).ToString("dd.MM.yyyy"));
            }
            else if (par_type == "String")
            {
                string_to_replace_with = '"' + Convert.ToString(par.Value) + '"';
            }
            else
            {
                //Break execution if the field has a type that is not handled here
                System.Diagnostics.Debugger.Break();
            }
        }

        cmd_txt_filled = ReplaceFirst(cmd_txt_filled, "?", string_to_replace_with);

    }

    cmd_txt_filled = cmd_txt_filled.Replace("= NULL", "IS NULL");

    //Get query text here to test it in Database Manager
    //System.Diagnostics.Debug.WriteLine(cmd_txt_filled);

    //Uncomment this to apply modified query template
    //oledb_e.Command.CommandText = cmd_txt;

    //Uncomment this to simply run the prepared update command
    //oledb_e.Command.CommandText = cmd_txt_filled;
}

public string ReplaceFirst(string text, string search, string replace)
{
    int pos = text.IndexOf(search);
    if (pos < 0)
    {
        return text;
    }
    return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}

private static string DateToParadoxDays(string date)
{
    return (Convert.ToDateTime(date) - Convert.ToDateTime("30.12.1899")).TotalDays.ToString();
}

是否有可能包含您正在使用的代码?搜索缺少的insert语句或delete语句。是否可以通过减少数据集突变的数量来减少您的问题?
public void Update(DataSet DBDataSet)
{
    DataAdapter.RowUpdating += before_update;
    DataAdapter.Update(DBDataSet);
}

public void before_update(object sender, EventArgs e)
{
    //Convert EventArgs to OleDbRowUpdatingEventArgs to be able to use OleDbCommand property
    System.Data.OleDb.OleDbRowUpdatingEventArgs oledb_e = (System.Data.OleDb.OleDbRowUpdatingEventArgs) e;

    //Get query template
    string cmd_txt = oledb_e.Command.CommandText;

    //Modify query template here to fix it
    //cmd_txt = cmd_txt.Replace("table_name", "\"table_name\"");

    //fill tamplate with values
    string cmd_txt_filled = cmd_txt;
    foreach(System.Data.OleDb.OleDbParameter par in oledb_e.Command.Parameters)
    {
        string par_type = par.DbType.ToString();
        string string_to_replace_with = "";

        if (par.Value.GetType().Name == "DBNull")
        {
            string_to_replace_with = "NULL";
        }
        else
        {
            if (par_type == "Int32")
            {
                par.Size = 4;
                string_to_replace_with=Convert.ToInt32(par.Value).ToString();
            }
            else if (par_type == "Double")
            {
                par.Size = 8;
                string_to_replace_with=Convert.ToDouble(par.Value).ToString().Replace(",",".");
            }
            else if (par_type == "DateTime")
            {
                par.Size = 8;
                /* In Paradox SQL queries you can't just specify the date as a string,
                 * it will result in incompatible types, you have to count the days
                 * between 30.12.1899 and the required date and specify that number
                 */
                string_to_replace_with = DateToParadoxDays(Convert.ToDateTime(par.Value).ToString("dd.MM.yyyy"));
            }
            else if (par_type == "String")
            {
                string_to_replace_with = '"' + Convert.ToString(par.Value) + '"';
            }
            else
            {
                //Break execution if the field has a type that is not handled here
                System.Diagnostics.Debugger.Break();
            }
        }

        cmd_txt_filled = ReplaceFirst(cmd_txt_filled, "?", string_to_replace_with);

    }

    cmd_txt_filled = cmd_txt_filled.Replace("= NULL", "IS NULL");

    //Get query text here to test it in Database Manager
    //System.Diagnostics.Debug.WriteLine(cmd_txt_filled);

    //Uncomment this to apply modified query template
    //oledb_e.Command.CommandText = cmd_txt;

    //Uncomment this to simply run the prepared update command
    //oledb_e.Command.CommandText = cmd_txt_filled;
}

public string ReplaceFirst(string text, string search, string replace)
{
    int pos = text.IndexOf(search);
    if (pos < 0)
    {
        return text;
    }
    return text.Substring(0, pos) + replace + text.Substring(pos + search.Length);
}

private static string DateToParadoxDays(string date)
{
    return (Convert.ToDateTime(date) - Convert.ToDateTime("30.12.1899")).TotalDays.ToString();
}