我有一个insert into tableA select from someTables,在我的select我有两个文本列,我将它们连接起来,例如colA + colB. 他们有类型varchar(n)。列应该TableA简单地是varchar(2n)?如果说我有,这对性能不利varchar(5*n)吗?
如果将两列连接varchar(n)起来,结果是否可能大于varchar(2n)或例如nvarchar(3n)?
当您连接 2 个(n)varchar值时,结果数据类型是加在一起的 2 个长度属性,或 8,000 字节(以较低者为准)。如果将 avarchar和 an连接起来nvarchar,varchar则将隐式转换为nvarchar第一个。
除非串联的值中至少有 1 个是MAX长度,否则返回数据类型不会转换为 aMAX并且任何尾随字符都将被截断。
以下面的例子为例,它们返回其别名的数据类型:
SELECT REPLICATE('A',10) + REPLICATE('B',10) AS varchar20,
REPLICATE(N'A',10) + REPLICATE(N'B',10) AS nvarchar20,
REPLICATE(N'A',10) + REPLICATE('B',5) AS nvarchar15,
REPLICATE('A',5000) + REPLICATE('B',5000) AS varchar8000, --Truncation occurs
REPLICATE(N'A',3000) + REPLICATE('B',3000) AS nvarchar4000, --Truncation occurs
REPLICATE(CONVERT(nvarchar(MAX),N'A'),3000) + REPLICATE('B',3000) AS nvarcharMAX;
Run Code Online (Sandbox Code Playgroud)
这可以使用以下方法进行验证dm_exec_describe_first_result_set:
SELECT [name], system_type_name
FROM sys.dm_exec_describe_first_result_set(N'SELECT REPLICATE(''A'',10) + REPLICATE(''B'',10) AS varchar20,
REPLICATE(N''A'',10) + REPLICATE(N''B'',10) AS nvarchar20,
REPLICATE(N''A'',10) + REPLICATE(''B'',5) AS nvarchar15,
REPLICATE(''A'',5000) + REPLICATE(''B'',5000) AS varchar8000, --Truncation occurs
REPLICATE(N''A'',3000) + REPLICATE(''B'',3000) AS nvarchar4000, --Truncation occurs
REPLICATE(CONVERT(nvarchar(MAX),N''A''),3000) + REPLICATE(''B'',3000) AS nvarcharMAX;',NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
显然,如果您连接 3 个(n)varchar值,则结果长度是 3 个长度值的总和,依此类推。
请注意,我明确说明了 8,000个字节而不是 8,000 或 4,000 个字符的长度。许多人混淆了长度值varchar和nvarchar它可以容纳的字符数,但这实际上不是真的,它是字节数;因为varchar它是 8,000 个单字节,因为nvarchar它是 4,000 个双字节。现在 SQL Server 支持 UTF-8 排序规则,这一点变得更加重要。
例如,下面的返回值是2666,因为我随机选择的字符 ( ?)每个字符使用3个字节。
SELECT LEN(REPLICATE(CONVERT(varchar(3),N'?' COLLATE Latin1_General_100_CI_AI_SC_UTF8),8000));
Run Code Online (Sandbox Code Playgroud)