主從表(如學生基本資料表 Student 與學生選課表 StudentSubject)同步更新是經典場景:每次主表新增/修改時,從表需全量刷新(先刪後增)。為保證資料一致性與效能,最佳實踐是將邏輯封裝在單一存儲過程中,配合交易控制。
關鍵技巧:將從表關鍵字(SubjectId)以逗號分隔字串(如 '101,102,105')作為參數傳入,存儲過程內用 CHARINDEX + SUBSTRING 循環解析並逐筆插入。
CREATE PROC SaveStudentInfo
@StudentId INT,
@StudentName VARCHAR(50),
@SubjectList VARCHAR(400) -- 逗號分隔的科目ID列表
AS
BEGIN
BEGIN TRAN;
-- 1. 更新/插入主表(略)
-- 2. 清空從表舊資料
DELETE FROM Tb_StudentSubject WHERE StudentId = @StudentId;
-- 3. 解析 @SubjectList 循環插入
DECLARE @SubjectIDsLen INT = LEN(@SubjectList),
@nStart INT = 1,
@nLast INT,
@SubjectIDLen INT,
@SubjectID INT;
IF @SubjectIDsLen > 0
BEGIN
WHILE @nStart <= @SubjectIDsLen
BEGIN
SET @nLast = CHARINDEX(',', @SubjectList, @nStart);
IF @nLast = 0 SET @nLast = @SubjectIDsLen + 1; -- 最後一個元素
SET @SubjectIDLen = @nLast - @nStart;
SET @SubjectID = SUBSTRING(@SubjectList, @nStart, @SubjectIDLen);
INSERT INTO Tb_StudentSubject (StudentId, SubjectID) VALUES (@StudentId, @SubjectID);
SET @nStart = @nLast + 1;
END
END
IF @@ERROR = 0 COMMIT TRAN ELSE ROLLBACK TRAN;
END
函數說明:
CHARINDEX(',', @SubjectList, @nStart):從指定位置尋找逗號,返回位置(1-based)。SUBSTRING(@SubjectList, @nStart, @SubjectIDLen):擷取子字串,起始位置 1-based。建議: 從表勿設自增主鍵,避免頻繁刪增導致身份值耗盡且無業務意義。此模式通用於訂單-明細、單據-分錄等主從場景。