首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C# 連 SQL Server 新增資料主鍵衝突:外鍵關聯缺失導致

     編輯:程式設計疑難解答

現象:在 SSMS 手動 `INSERT` 成功,但 WinForms 程式按鈕新增卻報「主鍵衝突」或「外鍵條件約束失敗」。

根本原因

資料表之間存在 **主從關係 (FK)**,例如:

CREATE TABLE consumer (
    cid INT PRIMARY KEY,
    name NVARCHAR(50)
);
CREATE TABLE sale (
    sid INT PRIMARY KEY,
    cid INT FOREIGN KEY REFERENCES consumer(cid), -- 從表
    amount DECIMAL(10,2)
);

向 `sale` 插入資料時,`cid` **必須已存在於 `consumer` 表**,否則拋出 FK 違規 (常被誤判為 PK 衝突)。

排查步驟

  1. 確認目標表的所有 FK 欄位。
  2. 檢查程式碼插入前,是否已先將主表資料寫入 (或確認該 FK 值存在)。
  3. 若是自動遞增 PK (`IDENTITY`),**勿在 INSERT 中指定 PK 值**,讓資料庫自動產生。
  4. 用 SQL Profiler / Extended Events 捕捉實際送出的 T-SQL,對比手動成功的語句差異。

修正程式碼範例 (ADO.NET)

using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand(
    "INSERT INTO sale (cid, amount) VALUES (@cid, @amt); SELECT SCOPE_IDENTITY();", conn))
{
    cmd.Parameters.AddWithValue("@cid", selectedConsumerId); // 必須是已存在的 cid
    cmd.Parameters.AddWithValue("@amt", amount);
    conn.Open();
    int newSid = Convert.ToInt32(cmd.ExecuteScalar());
    MessageBox.Show("新增成功,單號: " + newSid);
}

常見誤區

  • 以為 `sale.sid` 是 PK 所以衝突 → 實際是 `cid` FK 找不到對應主鍵。
  • 手動測試時順手在 `consumer` 先加了一筆,程式卻沒加 → 環境不一致。
  • 用 `DataSet`/`TableAdapter` 卻未設定 `ForeignKeyConstraint.AcceptRejectRule`,導致更新順序錯誤。

記住:**先有主表資料,才能寫從表資料**;用參數化查詢避免 SQL 注入,並檢查 FK 值來源,即可消除「莫名其妙的主鍵衝突」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved