【问题标题】:SqlException The INSERT statement conflicted with the FOREIGN KEY constraintSqlException INSERT 语句与 FOREIGN KEY 约束冲突
【发布时间】:2013-03-05 16:04:14
【问题描述】:

INSERT 语句与 FOREIGN KEY 约束 FK_Kupovina_Kupac 冲突。数据库OnlineApoteka、表dbo.Kupac、列“ID”中发生冲突。 声明已终止。

我真的很困惑不知道为什么不让?我在 throw ex 中报告了一个错误; ?

public static void Kupi(long lekID, int kolicina, double cena, long nacinIsporukeID, string korisnickoIme)
{
    SqlConnection con = new SqlConnection();
    try
    {
        con.ConnectionString = ConfigurationManager.ConnectionStrings["OnlineApotekaConnectionString"].ConnectionString;
        con.Open();

        string updateLager = @"
        UPDATE  Lager
        SET Kolicina=Kolicina-@Kolicina
        WHERE LekID=@LekID";

        SqlCommand cmd = new SqlCommand(updateLager, con);
        cmd.Parameters.AddWithValue("@LekID", lekID);
        cmd.Parameters.AddWithValue("@Kolicina", kolicina);

        cmd.ExecuteNonQuery();

        string insertIntoKupovina=@"
            INSERT INTO Kupovina (KupacID, LekID, Datum, Kolicina, Cena, NacinIsporukeID) 
            VALUES (@KupacID, @LekID, @Datum, @Kolicina, @Cena, @NacinIsporukeID)";

        cmd = new SqlCommand(insertIntoKupovina, con);
        cmd.Parameters.AddWithValue("@KupacID", KupacAdapter.GetID(korisnickoIme));
        cmd.Parameters.AddWithValue("@LekID", lekID);
        cmd.Parameters.AddWithValue("@Datum", DateTime.Now.Date);
        cmd.Parameters.AddWithValue("@Kolicina", kolicina);
        cmd.Parameters.AddWithValue("@Cena", cena);
        cmd.Parameters.AddWithValue("@NacinIsporukeID", nacinIsporukeID);

        cmd.ExecuteNonQuery();

    }
    catch (Exception ex)
    {
        throw ex;
    }
    finally
    {
        con.Close();
    }
}

我有一个购买按钮的例行事件。 当您单击 Kupi 时,应从表中删除 Lager 卷并放入 Kupac Kupovina

protected void kupiButton_Click(object sender, EventArgs e)
{
    KupovinaAdapter.Kupi(Convert.ToInt64(kupovinaGreedView.SelectedDataKey["LekID"].ToString()),
        Convert.ToInt32(kolicinaTextBox.Text),
        Convert.ToInt64(kupovinaGreedView.SelectedDataKey["Cena"].ToString()),
        Convert.ToInt64(nacinIsporukeDropDownList.SelectedValue),
        User.Identity.Name);
}

protected void kupovinaGreedView_SelectedIndexChanged(object sender, EventArgs e)
{
    if (!String.IsNullOrEmpty(kupovinaGreedView.SelectedDataKey["Lek"].ToString()))
    {
        LekLabel.Text = kupovinaGreedView.SelectedDataKey["Lek"].ToString();
    }

    if (!String.IsNullOrEmpty(kupovinaGreedView.SelectedDataKey["Kolicina"].ToString()))
    {
        kolicinaValidator.MaximumValue = kupovinaGreedView.SelectedDataKey["Kolicina"].ToString();
    }

【问题讨论】:

  • 请澄清您的问题。 '我不知道为什么我们不允许?我在 throw ex 中报告了一个错误; ?意思是?另外,请阅读“INSERT 语句与 FOREIGN KEY 约束冲突”的含义,看看它是否可以解释您的代码的问题。
  • 认为 OP 想知道为什么仍然会引发异常,而不是仅仅忽略...

标签: c# sql sql-server


【解决方案1】:

您收到错误的原因是数据库架构的定义方式。特别是表 Kupac 用于与表 Kupovina 的关系中,因此 Kupovina 中的 KupacID 必须与 Kupac 表中 ID 字段中的值匹配。

因此,您不能使用 KupacID 将记录插入到 Kupovina 表中,而该 Kupac 表中尚不存在 - 这是违反外键约束的行为。

你有两个选择:

  1. 确保首先将记录插入到 Kupac 表中
  2. 从数据库架构中删除外键约束,如果这具有商业意义

但是您应该检查KupacAdapter.GetID(korisnickoIme) 的输出,它应该提供KupacID 值。如果此方法由于某种原因未返回有效 ID(来自Kupovina 表的 ID),则插入将失败,如上所述。

如果您想知道为什么异常没有开始“已处理”,那是因为您的 catch 块中的代码。您基本上是在接受异常并重新抛出它,这有点毫无意义。你还不如根本没有 catch 块..

try {
   // ...
}
catch (Exception ex) {
    throw ex;    //  <--- this just re-throws the same exception that was caught!
}
finally { 

}

在大多数情况下,几乎等同于:

try {
   // ...
}    
finally { 

}

不同之处仅在于有多少堆栈跟踪与异常一起保留,但异常仍然冒泡。

【讨论】:

  • 这些是表 Kupac 和 Kupovina 的行:表 Kupac ID JMBG Ime Prezime Adresa KorisnickoIme Telefon Email 表 Kupac FK_Kupovina_Kupac 和表 Kupovina ID KupacID LekID Datum Kolicina Cena NacinIsporukeID
  • 你的问题到底是什么?我的回答对你有帮助吗?
  • INSERT 语句与 FOREIGN KEY 约束“FK_Kupovina_Kupac”冲突。冲突发生在数据库“OnlineApoteka”、表“dbo.Kupac”、列“ID”中。声明已终止。我检查了论坛上的所有答案正确的问题是我连接时的问题如何解决都不知道我错在哪里?
  • 请再次阅读我的回答。另外,如果您的名字是克罗地亚语,请理解上下文非常有限?! - 所以我们很难确定你的代码实际上应该代表什么。但更重要的是,您得到的错误是数据库级别冲突的结果。您正在尝试将一条记录插入 Kupovina,该记录应该与来自 Kupac 的记录相关,而该记录 不存在 int Kupac。这很可能与 KupacAdapter.GetID(korisnickoIme) 的结果有关
  • 其实提问者的代码和你的空try catch是有区别的:geekswithblogs.net/sdorman/archive/2007/08/20/…
【解决方案2】:

Kupac 表中没有您尝试插入到 Kupovina 表中的 KupacID

Kupac 表中的KupacID 列是主键,而Kupovina 表中的KupacID 列是指向主键的外键

阅读Foreign Keys

【讨论】:

    【解决方案3】:

    是的,您正在使用 catch (Exception ex) 捕获密钥违规 - 但是您随后会在那里重新抛出异常。

    调用例程中有错误处理程序吗?

    throw ex - 不“处理”错误 - 它只是引发另一个错误(尽管在这种情况下是同一个错误 - 已被捕获的那个)

    如果您期待这个特定错误,那么您应该通过catch (SqlException ex) 捕获这个特定错误 - 然后检查这个特定错误。如果是不是这个错误然后throw ex;备份调用堆栈...如果它这个错误那么你可以忽略(但最好只是首先避免这种插入...)

    【讨论】:

    • 我对常规错误没有头绪。当您单击表单上的 Kupi 按钮时,需要进行购买。我有一个 Kupi 按钮的常规事件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-27
    • 2021-05-30
    • 1970-01-01
    相关资源
    最近更新 更多