前言
本文針對 SQL Server 2005 開發高頻問題提供權威解答:預存程序並發超賣、新版索引增強、物件命名規範、CLR 預存程序適用性邊界。
1. 預存程序並發問題:查詢-插入非原子導致超賣
場景: 售票系統檢查剩餘座位 → 插入售票記錄。高併發下兩筆交易同時讀到 `free_seats > 0`,均插入導致超賣。
方案 A:唯一約束 + 業務鍵 (推薦)
-- 為每個座位建立唯一識別碼
CREATE TABLE Bookings (
BookingID INT IDENTITY,
SeatID INT NOT NULL UNIQUE, -- 關鍵:座位唯一約束
PassengerName VARCHAR(50),
BookingTime DATETIME DEFAULT GETDATE()
);
-- 應用層捕獲 2627/2601 錯誤碼 (唯一約束違反) → 重試/提示售罄
資料庫引擎保證原子性,零應用層鎖開銷。
方案 B:Service Broker 隊列單一消費者 (進階)
- 每班車建立一個 Service Broker 服務/隊列。
- 座位資訊作為訊息入隊 (`SEND ON CONVERSATION`)。
- 單一背景接收者 (`RECEIVE TOP(1) FROM queue`) 序列化處理售票邏輯。
- Broker 保證訊息**僅被消費一次**,天然解決並發衝突。
2. SQL Server 2005 索引增強 (無新關聯索引類型)
- 全文檢索索引: 完全重寫,整合於引擎,支援語義搜尋、詞幹分析、鄰近度查詢。
- XML 索引: 主 XML 索引 (解析 XML 為關聯行集) + 次級 XML 索引 (PATH/VALUE/PROPERTY) + 選擇性 XML 索引 (針對特定路徑)。
- 線上索引操作 (ONLINE = ON): `CREATE/REBUILD/DROP INDEX ... WITH (ONLINE = ON)` **不鎖定使用者存取**,維護窗口不再限於深夜。
- 包含欄位索引 (INCLUDE columns): 非叢集索引葉層包含非鍵值欄位,實現**覆蓋索引**避免書籤查找。
3. 表與欄位命名規範 (SQL Server 2000/2005 通用)
- 長度 1-128 字元。
- 首字元:Unicode 字母、`_`、`@`、`#`。
- 後續字元:Unicode 字母、數字、`@`、`$`、`#`、`_`。
- 特殊前綴語義: `@`=變數/參數,`#`=暫存表/程序,`##`=全域暫存,`@@`=系統函數 (避免自用)。
- 不可為保留字。含特殊字元需 `[]` 括起 (需 `QUOTED_IDENTIFIER ON`)。
4. 無 T-SQL 撰寫 CLR 預存程序:技術可行但無法存取資料
- CLR 程序透過 `SqlContext` / `SqlPipe` / ADO.NET (內部連線 `context connection=true`) 存取資料,**本質仍發送 T-SQL**。
- 適用場景:檔案 I/O、正則表達式、複雜數學/加密、Web Service 呼叫、外部組件互操作 — **非關聯資料邏輯**。
- 核心邏輯 (CRUD、聯結、聚合) **仍強烈建議用 T-SQL**:優化器成熟、集合式處理、計畫快取、統計資訊驅動。
5. CLR vs T-SQL 效能鐵律
在你的資料、你的伺服器、你的負載下,實測兩套方案。
一般規律:T-SQL 勝於標準 CRUD;CLR 勝於複雜運算/字串/程序式邏輯。