char 和 varchar (Transact-SQL)
適用於:sql Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW) SQL 分析端點Microsoft網狀架構倉儲中的 Microsoft Fabric SQL DatabaseMicrosoft網狀架構
固定大小 char 或變動大小 varchar 的字元資料類型。 從 SQL Server 2019 (15.x)開始,使用 UTF-8 啟用定序時,這些數據類型會儲存 Unicode 字元數據的完整範圍,並使用 UTF-8 字元編碼。 若指定非 UTF-8 定序,則這些資料類型只會存放該定序對應之字碼頁所支援的字元子集。
引數
char [ ( n ) ]
固定大小字串資料。 n 會定義字串大小 (單位為位元組),且必須是 1 到 8,000 之間的值。 針對單位元組編碼字元集 (例如Latin
),儲存大小是 n 位元組,而可儲存的字元數目也是 n。 對於多位元組編碼字元集,記憶體大小仍然是 n 個字節,但可以儲存的字元數目可能小於 n。 char 的 ISO 同義字為 character。 如需有關字元集的詳細資訊,請參閱單位元組和多位元組字元集。
varchar [ ( n | max ) ]
可變大小字串資料。 您可以使用 n 以位元組為單位來定義字串大小,該值可以介於 1 到 8,000,或使用 max 來表示資料行大小限制最多為 2^31-1 個位元組 (2 GB) 的儲存體。 針對單位元組編碼字元集 (例如Latin
),儲存大小是 n 位元組 + 2 位元組,而可儲存的字元數目也是 n。 對於多位元組編碼字元集,記憶體大小仍然是 n 個字節 + 2 個字節,但可以儲存的字元數目可能小於 n。 varchar 的 ISO 同義字是 char varying 或 character varying。 如需有關字元集的詳細資訊,請參閱單位元組和多位元組字元集。
備註
常見的誤解是假設 char(n) 和 varchar(n),n 會定義字元數。 但是,在 char(n) 和 varchar(n),n 會定義字串長度 (以位元組為單位) (0-8,000)。 n 一律不會定義可儲存的字元數。 這個概念類似於 nchar 和 nvarchar 的定義。
發生誤解的原因是,使用單一位元組編碼時,char 和 varchar 的儲存體大小是 n 位元組,而字元數目也是 n。 不過,針對多位元組編碼 (例如 UTF-8),較高的 Unicode 範圍 (128 至 1,114,111) 會使用二或多個位元組來產生單一字元。 例如,在定義為 char(10) 的資料行中,資料庫引擎可以儲存 10 個使用單一位元組編碼的字元 (Unicode 範圍 0 至 127),但使用多位元組編碼時,則小於 10 個字元 (Unicode 範圍 128 至 1,114,111)。 如需 Unicode 儲存和字元範圍的詳細資訊,請參閱 UTF-8 和 UTF-16 之間的儲存差異。
當資料定義或變數宣告陳述式中未指定 n 時,預設長度為 1。 若使用 CAST
和 CONVERT
函式時未指定 n,則預設長度為 30。
除非使用 COLLATE
子句指派特定定序;否則,使用 char 或 varchar 的物件會被指派資料庫的預設定序。 定序會控制用來儲存字元資料的字碼頁。
SQL Server 中的多位元組編碼包括:
一些東亞語言的雙位元組字元集 (DBCS) 使用字碼頁 936 與 950 (中文)、932 (日文) 或 949 (韓文)。
UTF-8 (具有字碼頁 65001)。
適用於:SQL Server 2019 (15.x) 和更新版本。
若您的網站支援多種語言:
- 從 SQL Server 2019 (15.x) 開始,請考慮使用支援 UTF-8 的定序來支援 Unicode 並將字元轉換問題降到最低。
- 若使用舊版 SQL Server 資料庫引擎,請考慮使用 Unicode nchar 或 nvarchar 資料類型,將字元轉換問題降到最低。
若使用 char 或 varchar,建議您:
- 當資料行資料項目的大小一致時,請使用 char。
- 當資料行資料項目的大小變化相當大時,請使用 varchar。
- 當資料行資料項目的大小變化相當大,且字串長度可能超出 8,000 位元組時,請使用 varchar(max) 。
如果 SET ANSI_PADDING
是OFF
執行 或 ALTER TABLE
時CREATE TABLE
,則會將 定義為 NULL
的 char 數據行處理為 varchar。
警告
每個非 Null 的 varchar(max) 或 nvarchar(max) 資料行都需要額外 24 個位元組的固定配置,而不利於排序作業期間 8,060 個位元組的資料列限制。 因此可能會對資料表中可建立的非 Null varchar(max) 或 nvarchar(max) 資料行數目建立隱含限制。
建立資料表時 (高於最大資料列大小超過允許上限 8,060 位元組所引發的一般警告) 或插入資料時,不會提供任何特殊錯誤。 如此大型的資料列可能會在某些一般作業 (如叢集索引鍵更新,或排序整個資料行集) 期間造成錯誤 (如錯誤 512)。
轉換字元資料
將字元運算式轉換成不同大小的字元資料類型時,對新資料類型而言太大的值會被截斷。 uniqueidentifier 類型因為轉換字元運算式之故,視為字元類型;因此會受到轉換成字元類型之截斷規則的影響。 請參閱範例一節。
當字元運算式被轉換成不同資料類型或大小的字元運算式時,例如從 char(5) 轉換成 varchar(5) ,或從 char(20) 轉換成 char(15) ,輸入數值的定序會被指派至轉換的數值。 如果將非字元運算式轉換成字元資料類型,會將目前資料庫的預設定序指派給轉換的數值。 不論哪一種狀況,都可以使用 COLLATE 子句指派特定的定序。
注意
支援 char 和 varchar 資料類型的字碼頁轉換,但不支援 text 資料類型的字碼頁轉換。 舊版的 SQL Server 不會報告字碼頁翻譯期間的資料遺失。
轉換成近似數值資料類型的字元運算式,可包含選擇性的指數標記法。 這個標記法是小寫 e
或大寫 E
加上選擇性的加號 (+
) 或減號 (-
),再接數字。
轉換成正確 numeric 資料類型的字元運算式必須由數字、小數點和選擇性的加號 (+
) 或減號 (-
) 組成。 前置的空白會被忽略。 字串不能用逗號分隔符號,如 123,456.00
中的千位分隔符號。
轉換成 money 或 smallmoney 資料類型的字元運算式也可以包含選擇性的小數點和錢幣符號 ($
)。 可用逗號分隔符號 (如 $123,456.00
)。
當空字串轉換為 int 時,其值會變成 0
。 當空字串轉換成日期時,其值會 變成 date - 也就是 1900-01-01
。
範例
A. 顯示在變數宣告中使用時,n 的預設值
下列範例顯示當用於變數宣告時,char 和 varchar 數據類型的預設值為 1。
DECLARE @myVariable AS VARCHAR = 'abc';
DECLARE @myNextVariable AS CHAR = 'abc';
--The following query returns 1
SELECT DATALENGTH(@myVariable), DATALENGTH(@myNextVariable);
GO
B. 顯示搭配 CAST 和 CONVERT 使用 varchar 時,n 的預設值
下列範例顯示搭配使用 char 或 varchar 資料類型與 CAST
和 CONVERT
函式時,n 的預設值是 30。
DECLARE @myVariable AS VARCHAR(40);
SET @myVariable = 'This string is longer than thirty characters';
SELECT CAST(@myVariable AS VARCHAR);
SELECT DATALENGTH(CAST(@myVariable AS VARCHAR)) AS 'VarcharDefaultLength';
SELECT CONVERT(CHAR, @myVariable);
SELECT DATALENGTH(CONVERT(CHAR, @myVariable)) AS 'VarcharDefaultLength';
C. 轉換資料以供顯示
下列範例將兩個資料行轉換為字元類型,並套用一個會以特定格式顯示資料的樣式。 money 類型會轉換為字元資料,並套用樣式 1
,在數值的小數點左側每三位數顯示一個逗號,並在小數點右側留下兩位數。 datetime 類型會轉換為字元資料,並套用樣式 3
,以 dd/mm/yy
格式顯示資料。 在 WHERE
子句中,money 類型將轉換為字元類型,以進行字串比較作業。
USE AdventureWorks2022;
GO
SELECT BusinessEntityID,
SalesYTD,
CONVERT(VARCHAR(12), SalesYTD, 1) AS MoneyDisplayStyle1,
GETDATE() AS CurrentDate,
CONVERT(VARCHAR(12), GETDATE(), 3) AS DateDisplayStyle3
FROM Sales.SalesPerson
WHERE CAST(SalesYTD AS VARCHAR(20)) LIKE '1%';
結果集如下所示。
BusinessEntityID SalesYTD DisplayFormat CurrentDate DisplayDateFormat
---------------- --------------------- ------------- ----------------------- -----------------
278 1453719.4653 1,453,719.47 2011-05-07 14:29:01.193 07/05/11
280 1352577.1325 1,352,577.13 2011-05-07 14:29:01.193 07/05/11
283 1573012.9383 1,573,012.94 2011-05-07 14:29:01.193 07/05/11
284 1576562.1966 1,576,562.20 2011-05-07 14:29:01.193 07/05/11
285 172524.4512 172,524.45 2011-05-07 14:29:01.193 07/05/11
286 1421810.9242 1,421,810.92 2011-05-07 14:29:01.193 07/05/11
288 1827066.7118 1,827,066.71 2011-05-07 14:29:01.193 07/05/11
D. 轉換 uniqueidentifier 數據
下列範例會將 uniqueidentifier 值轉換成 char 資料類型。
DECLARE @myid UNIQUEIDENTIFIER = NEWID();
SELECT CONVERT(CHAR(255), @myid) AS 'char';
下列範例會示範當值對於要轉換的目標資料類型而言太大時,資料的截斷方式。 因為 uniqueidentifier 類型限制為 36 個字元,所以超過該長度的字元會被截斷。
DECLARE @ID NVARCHAR(MAX) = N'0E984725-C51C-4BF4-9960-E1C80E27ABA0wrong';
SELECT @ID, CONVERT(UNIQUEIDENTIFIER, @ID) AS TruncatedValue;
結果集如下所示。
String TruncatedValue
------------------------------------------ ------------------------------------
0E984725-C51C-4BF4-9960-E1C80E27ABA0wrong 0E984725-C51C-4BF4-9960-E1C80E27ABA0