SqlException INSERT语句与FOREIGN KEY约束冲突

时间:2013-03-05 16:04:15

标签: c# sql sql-server

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

我真的很困惑我不知道为什么我们不允许?我报告了一个错误,在抛出前; ?

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();
    }
}

我有按钮Buy的例行事件。 当你点击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();
    }

3 个答案:

答案 0 :(得分:2)

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

因此,您无法使用Kupovina表中尚未存在的KupacID将记录插入Kupac表 - 它是外键约束违规。

您有两种选择:

  1. 确保首先将记录插入Kupac表
  2. 从数据库模式中删除外键约束(如果这样做是有商业意义的)
  3. 但是你应该检查KupacAdapter.GetID(korisnickoIme)的输出,它应该提供KupacID值。如果此方法由于某种原因未返回有效ID(来自Kupovina表),则插入将失败,如上所述。

    如果你想知道为什么异常没有开始"处理" 而不是因为catch块中的代码。你基本上是在接受异常并重新抛出它,这是毫无意义的。你可能根本就没有捕获块..

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

    在大多数情况下,几乎相当于:

    try {
       // ...
    }    
    finally { 
    
    }
    

    区别仅在于异常保留了多少堆栈跟踪,但异常仍然存在。

答案 1 :(得分:0)

Kupac表在您尝试插入KupacID

的表中没有Kupovina

KupacID表中的Kupac列是主键,而KupacID表中的Kupovina列是指向主键的外键< / p>

阅读Foreign Keys

答案 2 :(得分:0)

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

您在调用例程中是否有错误处理程序?

throw ex - 没有“处理”错误 - 它只是提出另一个错误(虽然,在这种情况下是同一个 - 已被捕获的那个)

如果您期望此特定错误,那么您应该通过catch (SqlException ex)捕获此特定错误 - 然后检查此特定错误。如果此错误,则throw ex;备份调用堆栈...如果 此错误则可以忽略(但会更好)首先要避免这种INSERT ...)