SQL Server 允許預存程序在建立時引用尚不存在的物件 (資料表、視圖等),這項特性稱為「延遲名稱解析」。本文深度解析其運作機制、相容性層級影響、游標輸出參數規則、臨時預存程序與自動啟動程序等進階主題。
-- 合法:建立時 test_table 不存在
CREATE PROC usp_TestDeferred
AS
SELECT * FROM test_table; -- 僅語法檢查通過
GO
-- 執行時若 test_table 不存在 → 錯誤 208: Invalid object name
EXEC usp_TestDeferred;
CREATE PROCEDURE
↓
語法解析 (Parser) → 生成解析樹
↓
儲存 sys.sql_modules / sys.objects
↓ (不檢查物件存在性)
執行 EXEC
↓
計畫快取查找
↓ (無有效計畫)
編譯
↓
解析所有物件名稱 (Name Resolution)
↓ (不存在 → 錯誤 208)
生成執行計畫 → 快取 → 執行
| 相容性層級 | 行為 |
|---|---|
| 65 (SQL 6.5 相容) | 程序內建立的暫存表引用會在建立時警告,執行時若不存在報錯 |
| 70+ (SQL 7.0+) | 完全延遲解析,建立時無警告,執行時才驗證 |
查看/設定:EXEC sp_dbcmptlevel 'dbname', 90 (90 = SQL 2005)
VARYING 與 OUTPUT 關鍵字VARYING 關鍵字暗示資料類型為 CURSORCREATE PROC usp_GetCursor @out_cursor CURSOR VARYING OUTPUT
AS
SET @out_cursor = CURSOR FOR SELECT * FROM sys.objects;
OPEN @out_cursor;
GO
| 游標類型 | 存儲程序結束時游標位置 | 返回給呼叫端的結果集 |
|---|---|---|
| FORWARD_ONLY (只進) | 第 N 行之後 | 第 N+1 行到結尾 |
| FORWARD_ONLY | 第一行之前 | 完整結果集 |
| FORWARD_ONLY | 最後一行之後 | 空結果集 (非 NULL) |
| SCROLL (可捲動) | 任意位置 | 完整結果集,保留位置 |
| 任意類型 | CLOSED 狀態 | NULL |
關鍵:關閉狀態僅在返回時生效,程序內可關閉後重開再返回。
| 類型 | 前綴 | 可見範圍 | 清理時機 |
|---|---|---|---|
| 區域臨時 | #proc_name | 僅建立連線 | Session 結束自動清除 |
| 全域臨時 | ##proc_name | 所有連線 | 最後使用 Session 結束清除 |
tempdb,任何用戶可建立sp_executesqlmaster 資料庫建立,由 sysadmin 建立-f) 可跳過執行sp_procoption @ProcName, 'startup', 'true/false'SELECT @@NESTLEVEL使用效能監視器計數器:
| 物件 | 計數器 |
|---|---|
| SQLServer:Buffer Manager | Cache Size (pages) |
| SQLServer:Cache Manager | Cache Hit Ratio |
SQL Server 物件引用機制核心在於編譯時解析、執行時驗證。延遲名稱解析提供開發彈性,但也意味著部署前必須完整執行測試驗證所有物件存在。理解游標輸出參數規則、臨時程序生命週期、自動啟動機制與嵌套限制,是編寫健壯預存程序的關鍵。