Files
thinkyu/報到系統/SQL/SignUp序號初始化使用指南.md
T
sryang 577060bc78 chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore
- 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
2026-09-10 09:42:37 +08:00

329 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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+