SQL Server: 将截断字符串或二进制数据,快速判断哪个字段超长

SQL Server: 将截断字符串或二进制数据,快速判断哪个字段超长

吉普赛的歌

上面的出错, 用 SQL Server 的人基本上都遇到过。如果某个表的字段少还好, 有几十甚至更多字段就抓瞎了,如何快速判断哪个字段超长呢?

先创建一个存储过程:

 
  1. IF OBJECT_ID('Proc_Util_GetLenOverflowColumns') IS NOT NULL

  2. DROP PROC Proc_Util_GetLenOverflowColumns

  3. GO

  4. -- =============================================

  5. -- Author: yenange

  6. -- Create date: 2020-10-09

  7. -- Description: 判断字段名相同的两个表,哪些字段可能会有插入问题

  8. -- =============================================

  9. CREATE PROCEDURE dbo.Proc_Util_GetLenOverflowColumns

  10. @targetTableName NVARCHAR(100), --要插入的目标表

  11. @tmpTableName NVARCHAR(100) --插入数据生成的临时表

  12. AS

  13. BEGIN

  14. SET NOCOUNT ON;

  15. ;WITH t1 AS (

  16. SELECT * FROM sys.columns AS a WHERE a.object_id=OBJECT_ID(@targetTableName)

  17. ),t2 AS (

  18. SELECT * FROM sys.columns AS b WHERE b.object_id=OBJECT_ID(@tmpTableName)

  19. )

  20. SELECT

  21. OBJECT_NAME(t1.OBJECT_ID) AS targetTableName

  22. , OBJECT_NAME(t2.OBJECT_ID) AS tmpTableName

  23. , t1.name AS columnName

  24. , t1.max_length AS targetMaxlen

  25. , t2.max_length AS tmpMaxlen

  26. , tp1.name AS targetColType

  27. , tp2.name AS tmpColType

  28. FROM t1 INNER JOIN t2 ON t1.name=t2.name

  29. INNER JOIN sys.types AS tp1 ON t1.system_type_id=tp1.system_type_id

  30. INNER JOIN sys.types AS tp2 ON t2.system_type_id=tp2.system_type_id

  31. WHERE t1.max_length<t2.max_length

  32. AND t1.max_length!=-1 --排除原表字段为 max 的情况

  33. AND tp1.name!='sysname'

  34. AND tp2.name!='sysname'

  35. END

  36. GO

  37.  

下面我们来测试下是否能找到可能有问题的字段:

 
  1. USE tempdb

  2. GO

  3. IF OBJECT_ID('t1') IS NOT NULL

  4. DROP TABLE t1

  5. GO

  6. CREATE TABLE t1(

  7. id INT PRIMARY KEY,

  8. n NVARCHAR(10) NOT NULL,

  9. isEnabled BIT NOT NULL

  10. )

  11. GO

  12. INSERT INTO t1 VALUES(99999999,'12345678901',2)

  13. /*

  14. 消息 8152,级别 16,状态 4,第 12 行

  15. 将截断字符串或二进制数据。

  16. 语句已终止。

  17. */

  18. --------------- 以上为测试表及模拟插入时产生的错误 -------------

  19.  
  20. --1. 将需要插入的数据, 先插入到临时用的普通表

  21. --注:字段名要完全与目标表的相同,方便下一步的对比

  22. IF OBJECT_ID('tmp') IS NOT NULL

  23. DROP TABLE tmp

  24. GO

  25. SELECT *

  26. INTO tmp

  27. FROM (

  28. SELECT 99999999 AS id

  29. ,N'12345678901' AS n

  30. ,1 AS isEnabled

  31. UNION ALL

  32. SELECT 99999999999 AS id

  33. ,N'12345678901234' AS n

  34. ,0 AS isEnabled

  35. ) AS tt

  36. --(1 行受影响)

  37. GO

  38. --2. 比较目标表与临时表的字段差异,获取到可能长度不够的字段名称

  39. EXEC Proc_Util_GetLenOverflowColumns

  40. @targetTableName ='t1', --要插入的目标表

  41. @tmpTableName ='tmp' --插入数据生成的临时表

结果:

根据结果, 把字段类型或长度对应改一下, 就可以避免出错了。

注:临时产生的表,用完记得删除( drop )。

简单吧?

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值