| 標準類型 | 語法 | SQL Server 2005/2008+ | 儲存特性 | 最大長度 |
|---|---|---|---|---|
| CHARACTER / CHAR | `CHAR(n)` | `CHAR(n)` | 固定長度,空白填充 | 8,000 位元組 |
| CHARACTER VARYING / VARCHAR | `VARCHAR(n)` | `VARCHAR(n)` | 變動長度,實際長度+2位元組 | 8,000 位元組 |
| NATIONAL CHARACTER / NCHAR | `NCHAR(n)` | `NCHAR(n)` | 固定長度 Unicode (UTF-16) | 4,000 字元 |
| NATIONAL CHARACTER VARYING / NVARCHAR | `NVARCHAR(n)` | `NVARCHAR(n)` | 變動長度 Unicode | 4,000 字元 |
| - (大型物件) | - | `VARCHAR(MAX)` / `NVARCHAR(MAX)` | LOB 儲存,溢位頁 | 2^31-1 位元組/字元 |
| - (舊型別) | - | `TEXT` / `NTEXT` | **已棄用**,LOB 指標 | 2^31-1 |
| 型別 | 參數 n 代表 | 最大 n | 實際儲存上限 |
|---|---|---|---|
| `CHAR(n)` / `VARCHAR(n)` | 位元組數 | 8,000 | 8,000 位元組 |
| `NCHAR(n)` / `NVARCHAR(n)` | **字元數** (非位元組) | 4,000 | 8,000 位元組 (4,000 字元 × 2) |
常見錯誤:`NVARCHAR(100)` 以為可存 100 位元組,實際可存 100 字元 (中文 100 字,英文 100 字母)。
| 操作 | 推薦函數 | 避免/注意 |
|---|---|---|
| 連接 | `CONCAT()` (2012+) 自動處理 NULL / `+` (舊版) | `+` 遇 NULL 結果為 NULL |
| 長度 | `LEN()` (不含尾空白) / `DATALENGTH()` (位元組數) | `LEN` 忽略尾空白,`CHAR` 欄位需 `DATALENGTH` |
| 截取 | `SUBSTRING` / `LEFT` / `RIGHT` | 索引 1 起算 |
| 修剪 | `LTRIM`/`RTRIM` / `TRIM` (2017+) | `CHAR` 欄位尾空白語義模糊 |
| 大小寫 | `UPPER`/`LOWER` | 受排序規則影響 |
| 替換 | `REPLACE` / `TRANSLATE` (2017+) | `REPLACE` 全掃描,大量資料慎用 |
| 模式比對 | `LIKE` / `PATINDEX` | 前導萬用字元 `%abc` 導致索引掃描 |
| 來源型別 | SQL Server 目標 | 注意事項 |
|---|---|---|
| Oracle `CHAR(n)` / `VARCHAR2(n)` | `CHAR(n)` / `VARCHAR(n)` | Oracle `VARCHAR2` 語義同 `VARCHAR`;長度單位同為位元組 |
| Oracle `NCHAR` / `NVARCHAR2` | `NCHAR` / `NVARCHAR` | Oracle 字元語義預設,SQL Server 需確認 n 為字元數 |
| Oracle `CLOB` / `NCLOB` | `VARCHAR(MAX)` / `NVARCHAR(MAX)` | LOB 存取 API 差異大,應用層需改寫 |
| MySQL `CHAR` / `VARCHAR` (utf8mb4) | `NCHAR` / `NVARCHAR` | MySQL `VARCHAR(n)` n 為字元數,映射至 `NVARCHAR(n)` |
| PostgreSQL `VARCHAR(n)` / `TEXT` | `NVARCHAR(n)` / `NVARCHAR(MAX)` | PostgreSQL 無固定長度型別,`CHAR(n)` 會空白填充 |
| 錯誤現象 | 根因 | 修正 |
|---|---|---|
| 中文存入 `VARCHAR` 變亂碼 | 編碼頁不支援 Unicode | 改用 `NVARCHAR`,連線字串無需特殊設定 |
| `WHERE VarcharCol = N'值'` 索引掃描 | 隱式轉換 `VarcharCol` → Unicode | 參數化傳入 `SqlDbType.VarChar`,或欄位改 `NVARCHAR` |
| `LEN(CHAR(10))` 回傳 10 即使只存 'A' | `CHAR` 尾空白不計入 `LEN`,但 `DATALENGTH` 回傳 10 | 理解語義差異,比較用 `RTRIM` 或改 `VARCHAR` |
| `VARCHAR(MAX)` 無法建立索引 | LOB 型別限制 | 改 `VARCHAR(8000)` 或用計算欄位 `CHECKSUM`/`HASHBYTES` 索引 |
下一篇將講解建立與修改資料表:`CREATE TABLE`、`ALTER TABLE`、`DROP TABLE`、約束條件、索引、身分識別欄位、分區表等 DDL 完整實戰指南。