Access 專案 (.adp) 直接連接 SQL Server 時,Access 原生函數 Nz()、IsNull() 在 T-SQL 環境下行為不同甚至失效。本文深入分析空值處理差異,提供對應的 T-SQL 替代方案與最佳實務。
空值 ≠ 空字串 ≠ 零值。空值代表「未知」、「尚未決定」、「不適用」。正確處理空值能:
NULL + 100 = NULL 導致報表失真)| Access 函數 | T-SQL 等效 | 行為差異 | 適用範圍 |
|---|---|---|---|
Nz(expr, valueIfNull) | ISNULL(expr, valueIfNull) / COALESCE(expr, valueIfNull) | Nz 只接受 2 參數;COALESCE 支援多參數、標準 SQL | Access: 所有地方 T-SQL: 查詢、預存程序、檢視表 |
IsNull(expr) (傳回 Boolean) | expr IS NULL / ISNULL(expr, 0) (不同語意!) | 陷阱:T-SQL ISNULL() 是取代函數,非判斷函數 | Access: VBA、查詢準則 T-SQL: WHERE、CASE、CHECK 條件約束 |
IsNull(expr) 在 VBA | 無直接對應 | T-SQL 無 VBA 環境 | 僅 Access VBA |
-- Access: IsNull(Field) → True/False
-- T-SQL 錯誤用法:
SELECT ISNULL(MiddleName) -- 語法錯誤!ISNULL 需 2 參數
-- T-SQL 正確判斷空值:
SELECT CASE WHEN MiddleName IS NULL THEN 1 ELSE 0 END AS HasMiddleName
-- 或
SELECT IIF(MiddleName IS NULL, 1, 0) AS HasMiddleName -- SQL 2012+
CREATE VIEW vw_EmployeeDisplay AS
SELECT
EmployeeID,
FirstName,
LastName,
ISNULL(MiddleName, '') AS MiddleName, -- 空值轉空字串
ISNULL(Title, '未指定職稱') AS Title, -- 空值轉預設文字
COALESCE(HomePhone, MobilePhone, '無連絡電話') AS ContactPhone, -- 多欄位備援
CASE WHEN BirthDate IS NULL THEN '未提供' ELSE CONVERT(VARCHAR(10), BirthDate, 111) END AS BirthDateDisplay
FROM Employees
MiddleNameDisplay)=Date()、="N/A")Is Not Null 強制必填Nz() → 改用 ISNULL() / COALESCE()
IsNull() → 改用 IS NULL / IIF(... IS NULL, ...)
DLookup() → 改用預存程序/檢視表 JOIN
DCount() → 改用 COUNT(*) 配合 WHERE
DMax/DMin → 改用 MAX()/MIN() 配合 WHERE
DateDiff() → 改用 DATEDIFF() (參數順序不同!)
Format() → 改用 CONVERT()/FORMAT() (SQL 2012+)
IIf() → 改用 CASE WHEN / IIF() (SQL 2012+)
NOT NULL + DEFAULT,源頭阻擋空值IIF(ISNULL(...), '顯示文字', ...) 或 Format() 控制輸出-- 擴充屬性記錄空值業務含義
EXEC sp_addextendedproperty
@name = N'NullMeaning',
@value = N'尚未進行健檢',
@level0type = N'SCHEMA', @level0name = 'dbo',
@level1type = N'TABLE', @level1name = 'Patients',
@level2type = N'COLUMN', @level2name = 'LastCheckupDate'
-- 查詢中繼資料
SELECT
OBJECT_NAME(c.object_id) AS TableName,
c.name AS ColumnName,
ep.value AS NullMeaning
FROM sys.columns c
JOIN sys.extended_properties ep ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
WHERE ep.name = 'NullMeaning'
ADP 開發的核心心法:將空值處理下推至資料庫層 (檢視表/預存程序),前端只負責呈現。善用 ISNULL、COALESCE、CASE、IIF 建立乾淨的顯示層,避免 Access 與 T-SQL 函數語意衝突導致的難除錯問題。