類型轉換是 SQL 查詢中無處不在的操作,CAST 與 CONVERT 是 T-SQL 顯式轉換的雙核心。前者符合 ANSI SQL 標準,移植性強;後者擁有豐富的 style 參數,專為日期/數值格式化而生。本文將深度對比二者語法、參數、風格代碼、性能差異與最佳實踐,助你寫出健壯、高效、可維護的轉換邏輯。
| 函數 | 語法 | 標準 | 靈活度 |
|---|---|---|---|
CAST | CAST ( expression AS data_type ) | ANSI SQL-92 | 僅類型轉換,無格式控制 |
CONVERT | CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) | T-SQL 專有 | 支援 style 格式化日期/數值 |
bigint、sql_variant、xml、datetime2 等。length 僅適用於 char/varchar/nchar/nvarchar/binary/varbinary,省略則默認 30 (字符) 或 1 (二進制)。style 僅在 日期時間 ↔ 字符、浮點數/貨幣 ↔ 字符 轉換時生效。以下為常用日期風格代碼 (加 100 可獲世紀位,如 101 = mm/dd/yyyy):
| style | 輸出格式 | 標準/示例 | 適用類型 |
|---|---|---|---|
| 0 / 100 | mon dd yyyy hh:miAM/PM | 默認 / Jan 1 2023 1:30PM | datetime/smalldatetime |
| 101 | mm/dd/yyyy | 美國 / 01/01/2023 | datetime/smalldatetime |
| 102 | yyyy.mm.dd | ANSI / 2023.01.01 | datetime/smalldatetime |
| 103 | dd/mm/yyyy | 英國/法國 / 01/01/2023 | datetime/smalldatetime |
| 112 | yyyymmdd | ISO / 20230101 | datetime/smalldatetime (最推薦排序/分區) |
| 120 / 121 | yyyy-mm-dd hh:mi:ss(.fff) | ODBC 標準 / 2023-01-01 13:30:45.123 | datetime2/datetime (121 含毫秒) |
| 126 / 127 | yyyy-mm-ddThh:mi:ss.mmm (Z/時區) | ISO8601 / 2023-01-01T13:30:45.123Z | datetimeoffset (XML/JSON 交互首選) |
浮點/貨幣風格: 0(默認, 科學記數法)、1(固定小數, 逗號分組)、2(科學記數法, 無逗號)。
SQL Server 遵循 數據類型優先級 自動進行隱式轉換 (如 int + varchar → int)。但隱式轉換會導致:
WHERE VarcharCol = 123 觸發掃描而非查找。SELECT 'abc' + 1 報錯,而 SELECT '123' + 1 返回 124。DATEFORMAT/LANGUAGE 影響。鐵律: 所有跨類型操作必須顯式 CAST/CONVERT,消除歧義與風險。
SELECT CONVERT(varchar(10), GETDATE(), 112) AS ISO_Date, -- 20230101
CONVERT(varchar(19), GETDATE(), 120) AS ODBC_DateTime, -- 2023-01-01 13:30:45
CONVERT(varchar(27), SYSDATETIMEOFFSET(), 127) AS ISO8601_TZ; -- 2023-01-01T13:30:45.1234567+08:00
-- 安全轉換:ISO 8601 格式不受 DATEFORMAT 影響
SELECT CAST('2023-01-01T13:30:45.123' AS datetime2(3));
SELECT CONVERT(datetime2(3), '2023-01-01T13:30:45.123', 126);
SELECT CONVERT(varchar(20), 1234567.89, 1) AS WithComma; -- 1,234,567.89
SELECT CONVERT(varchar(20), CAST(1234567.89 AS money), 1) AS MoneyStyle; -- 1,234,567.89
-- 字串 → 二進制 (0x 開頭)
SELECT CONVERT(varbinary(100), 'Hello', 0); -- 0x48656C6C6F
-- 二進制 → 字串
SELECT CONVERT(varchar(100), 0x48656C6C6F, 0); -- Hello
-- 轉換失敗返回 NULL 而非報錯,極適合髒數據清洗
SELECT TRY_CAST('abc' AS int) AS Result; -- NULL
SELECT TRY_CONVERT(date, '2023-13-01', 112) AS Result; -- NULL
CAST 與 CONVERT (無 style) 編譯為相同內部運算子,性能無差異。style 參數增加格式化開銷,但通常可忽略;避免在大結果集上頻繁格式化,改由應用層處理。WHERE CAST(DateCol AS date) = '20230101' 導致索引掃描,改寫為 WHERE DateCol >= '20230101' AND DateCol < '20230102'。CAST,避免 CONVERT 的 style 參數。TRY_CAST/TRY_CONVERT 增強容錯;日期用 datetime2、date、time、datetimeoffset 替代舊類型。yyyy-mm-ddThh:mi:ss.mmm),消除 DATEFORMAT 依賴。CAST 以標準化、簡潔著稱,CONVERT 以 style 參數掌控格式化細節。現代 T-SQL 開發應默認使用 TRY_CAST/TRY_CONVERT 保障數據質量,日期時間轉換堅持 ISO 8601 格式,數值格式化下推應用層。記住:顯式優於隱式、標準優於專有、安全優於高效,是類型轉換的三大黃金法則。