# SignUp 序號初始化 SQL 使用指南 ## 概述 本指南提供多個 SQL 腳本,用於初始化和管理 `SignUp` 表中的 `SeqNo`(序號)欄位。 ## 前置條件 - SQL Server 2005 或更高版本 - 擁有 `SignUp` 表的修改權限 - 建議先備份資料庫 ## 文件清單 ### 1. 初始化SignUp序號.sql **用途**:最簡單的初始化腳本,一鍵補充所有序號 **功能**: - ✅ 為 SeqNo = 0 或 NULL 的記錄自動編號 - ✅ 按活動(CourseID)分組 - ✅ 按ID順序編號 - ✅ 包含驗證查詢 **適用場景**: - 首次初始化序號 - 批量補充缺失的序號 **執行步驟**: 1. 在 SQL Server Management Studio 中開啟此文件 2. 修改事務範圍(如需要) 3. 全選所有代碼並執行 4. 檢查結果輸出確認更新成功 ### 2. SignUp序號管理工具.sql **用途**:提供多種序號管理場景的工具集 **包含的場景**: #### 場景1:初始化所有未設定的序號 ```sql -- 將此代碼段取消註釋並執行 UPDATE SignUp SET SeqNo = rn.RowNum FROM SignUp su INNER JOIN ( SELECT ID, ROW_NUMBER() OVER (PARTITION BY CourseID ORDER BY ID ASC) AS RowNum FROM SignUp WHERE SeqNo = 0 OR SeqNo IS NULL ) rn ON su.ID = rn.ID ``` **適用**:批量初始化序號 #### 場景2:重新編號特定活動 ```sql DECLARE @CourseID INT = 1; -- 改為目標活動編號 UPDATE SignUp SET SeqNo = rn.RowNum FROM SignUp su INNER JOIN ( SELECT ID, ROW_NUMBER() OVER (ORDER BY ID ASC) AS RowNum FROM SignUp WHERE CourseID = @CourseID ) rn ON su.ID = rn.ID ``` **適用**:某個活動序號亂掉,需要重新編號 #### 場景3:檢查序號異常 提供幾個檢查查詢: - 查看 SeqNo = 0 或 NULL 的記錄 - 查看序號重複的記錄 - 查看序號不連續的活動 #### 場景4:統計各活動序號分佈 查看所有活動的序號狀態是否正常 #### 場景5:修復所有序號異常 完整的修復腳本,修復所有有問題的序號 #### 場景6:數據備份檢查 查看備份表中的歷史記錄 ## 使用步驟 ### 步驟1:檢查當前狀態 ```sql -- 執行此查詢查看異常 SELECT * FROM SignUp WHERE SeqNo = 0 OR SeqNo IS NULL; SELECT * FROM SignUp WHERE (SeqNo = 0 OR SeqNo IS NULL) OR SeqNo > 1000; ``` ### 步驟2:執行初始化 根據需要選擇相應的場景腳本執行 ### 步驟3:驗證結果 ```sql -- 驗證所有記錄是否都有序號 SELECT COUNT(*) AS [未設定序號的筆數] FROM SignUp WHERE SeqNo = 0 OR SeqNo IS NULL; -- 檢查序號是否重複 SELECT CourseID, SeqNo, COUNT(*) FROM SignUp WHERE SeqNo > 0 GROUP BY CourseID, SeqNo HAVING COUNT(*) > 1; ``` ## 關鍵的 SQL 邏輯 ### ROW_NUMBER() 函數 ```sql ROW_NUMBER() OVER (PARTITION BY CourseID ORDER BY ID ASC) AS RowNum ``` **說明**: - `PARTITION BY CourseID` - 按活動分組 - `ORDER BY ID ASC` - 按ID升序排列 - 結果:每個活動內的記錄會被編號為 1, 2, 3... ### 更新語句 ```sql UPDATE SignUp SET SeqNo = rn.RowNum FROM SignUp su INNER JOIN (...) rn ON su.ID = rn.ID WHERE su.SeqNo = 0 OR su.SeqNo IS NULL ``` **說明**: - 只更新 SeqNo = 0 或 NULL 的記錄 - 聯接查詢結果和原表 - 將計算的序號寫入 SeqNo 欄位 ## 執行範例 ### 範例1:初始化所有序號 ```sql BEGIN TRANSACTION; UPDATE SignUp SET SeqNo = rn.RowNum FROM SignUp su INNER JOIN ( SELECT ID, ROW_NUMBER() OVER (PARTITION BY CourseID ORDER BY ID ASC) AS RowNum FROM SignUp ) rn ON su.ID = rn.ID WHERE su.SeqNo = 0 OR su.SeqNo IS NULL; -- 查看更新筆數 SELECT @@ROWCOUNT AS [更新筆數]; COMMIT TRANSACTION; ``` ### 範例2:特定活動重新編號 ```sql BEGIN TRANSACTION; -- 重新編號活動編號為 5 的所有參加人員 UPDATE SignUp SET SeqNo = rn.RowNum FROM SignUp su INNER JOIN ( SELECT ID, ROW_NUMBER() OVER (ORDER BY ID ASC) AS RowNum FROM SignUp WHERE CourseID = 5 ) rn ON su.ID = rn.ID WHERE su.CourseID = 5; SELECT '重新編號完成' AS [結果]; COMMIT TRANSACTION; ``` ### 範例3:查看各活動的序號狀態 ```sql SELECT c.ID AS [活動編號], c.CourseName AS [活動名稱], COUNT(s.ID) AS [人數], CASE WHEN MAX(s.SeqNo) = COUNT(s.ID) THEN '✓ 正常' ELSE '✗ 異常' END AS [狀態] FROM Classes c LEFT JOIN SignUp s ON c.ID = s.CourseID GROUP BY c.ID, c.CourseName ORDER BY c.ID; ``` ## 常見問題 ### Q1:如何檢查序號是否已經初始化? ```sql SELECT COUNT(*) FROM SignUp WHERE SeqNo = 0 OR SeqNo IS NULL; ``` - 返回 0:全部已初始化 - 返回 > 0:還有未初始化的記錄 ### Q2:如何查看某個活動的序號? ```sql SELECT ID, Name, Mobile, SeqNo FROM SignUp WHERE CourseID = 1 ORDER BY SeqNo; ``` ### Q3:如何檢查序號是否連續? ```sql SELECT CourseID, MIN(SeqNo), MAX(SeqNo), COUNT(*) FROM SignUp WHERE SeqNo > 0 GROUP BY CourseID; ``` - 如果 `MAX(SeqNo) = COUNT(*)`,說明序號連續且正常 ### Q4:如何復原被修改的序號? ```sql -- 查看備份表 SELECT * FROM SignUp_BAK WHERE DB_TRMOD = 'UPDATE' ORDER BY DB_TRDAT DESC LIMIT 100; ``` ### Q5:執行失敗怎麼辦? 1. 檢查是否有足夠的 UPDATE 權限 2. 檢查 SignUp 表是否存在 3. 檢查是否有其他鎖定操作 4. 查看 SQL Server 錯誤日誌 ## 回滾方案 如果執行出錯,可以使用備份表進行復原: ```sql -- 查看備份表中的 UPDATE 操作 SELECT * FROM SignUp_BAK WHERE DB_TRMOD = 'UPDATE' ORDER BY DB_TRDAT DESC; -- 使用備份數據復原(謹慎操作!) -- 建議聯繫數據庫管理員 ``` ## 安全建議 1. **執行前備份** ```sql BACKUP DATABASE [報到系統] TO DISK = 'D:\Backup\報到系統.bak' ``` 2. **使用事務** ```sql BEGIN TRANSACTION; -- 執行更新 -- 檢查結果 COMMIT TRANSACTION; -- 或 ROLLBACK TRANSACTION; ``` 3. **逐步驗證** - 先查看要更新的記錄 - 執行更新 - 立即驗證結果 4. **記錄操作** - 記錄執行時間 - 記錄更新筆數 - 記錄任何錯誤 ## 技術詳情 ### 序號編號邏輯 使用 `ROW_NUMBER()` 窗口函數進行分區編號: ``` 活動1: ID=1 → SeqNo=1 ID=3 → SeqNo=2 ID=5 → SeqNo=3 活動2: ID=2 → SeqNo=1 ID=4 → SeqNo=2 ID=6 → SeqNo=3 ``` ### 性能考量 - `ROW_NUMBER()` 在大資料集上性能最優 - 使用 `WHERE SeqNo = 0 OR SeqNo IS NULL` 減少更新範圍 - 建議為 `CourseID` 和 `SeqNo` 建立索引 ### 兼容性 支援的 SQL Server 版本: - ✅ SQL Server 2005+ - ✅ SQL Server 2008/R2 - ✅ SQL Server 2012+ - ✅ SQL Server 2016+ - ✅ SQL Server 2019+ - ✅ SQL Server 2022+ ## 完成後檢查清單 - [ ] 備份已執行 - [ ] 事務已提交 - [ ] 所有記錄都有序號(SeqNo > 0) - [ ] 沒有序號重複 - [ ] 序號按預期連續 - [ ] 應用程序正常運行 --- **最後更新**:2024年 **適用版本**:SQL Server 2005+