sqlserver CAST(AS nvarchar)的坑 —— 类型转换截断数据

开发反馈数据同步时,写入表的数据被截断,例如:

  • 源数据是:ABC_DEFGHIJKL,Reference:ABC-31000000-ABCDEF,AES123456789
  • 写入后只有:ABC_DEFGHIJKL,Reference:ABC

查看该表对应字段类型为nvarchar(100),而同步使用的插入语句是 INSERT INTO xxx VALUES(CAST ( AS nvarchar))。

 

创建一个测试表插入测试数据。

create table tmp0327(name nvarchar(100));
INSERT INTO tmp0327 VALUES(CAST ('ABC_DEFGHIJKL,Reference:ABC-31000000-ABCDEF,AES123456789' AS nvarchar));
INSERT INTO tmp0327 VALUES('ABC_DEFGHIJKL,Reference:ABC-31000000-ABCDEF,AES123456789');

Select datalength(name),* from tmp0327;

可以看到经过转换的字符串被截断了,而未转换的正常。怀疑CAST(AS nvarchar)有自动截断功能,去查一下官方文档的定义发现有如下介绍:

如果在字段定义或变量声明时不指定nvarchar(n) n的值,n默认是1;如果在CAST和CONVERT函数中,不指定n则默认是30。根据前面截图也可以看到 ABC_DEFGHIJKL,Reference:ABC-31 刚好是30位,长度为60。

所以如果我们希望插入时数据不被截断有两种方法:

  • 不要用显示转换,sqlserver会有隐式转换替你转
  • 如果一定要用,要指定n的值,例如
INSERT INTO tmp0327 VALUES(CAST ('ABC_DEFGHIJKL,Reference:ABC-31000000-ABCDEF,AES123456789' AS nvarchar(100)));

另外可以再验证下官方文档说的,在字段定义或变量声明时不指定nvarchar(n) n的值,n默认是1

create table tmp0327_2(name nvarchar);

去看sqlserver中表的定义,可以看到确实是nvarchar(1)

 

参考

https://docs.microsoft.com/en-us/sql/t-sql/data-types/char-and-varchar-transact-sql?view=sql-server-ver15

https://www.cnblogs.com/firstdream/p/5511404.html

发布了295 篇原创文章 · 获赞 35 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/Hehuyi_In/article/details/105147899