如何确定插入时哪一列会引发算术溢出错误?
想象一下,一张桌子上有上百个不同的列。 想象一下,我想从我要将数据复制到基表的位置有一个用户数据表。 所以我写了这个简单的插入选择语句,并弹出此错误。 那么,找出哪一列会引发错误,最优雅的方法是什么?
我对解决方案的初步想法是将它包装在一个事务中,我最终将回滚并使用一种分而治之的方法:
begin tran
insert into BaseTable (c1,c2,c3,...,cN)
select c1,c2,c3,...,cN
from UserTable
rollback tran
这显然失败了。 因此,我们将列设置为一半,如下所示:
begin tran
insert into BaseTable (c1,c2,c3,...,cK) --where K = N/2
select c1,c2,c3,...,cK --where K = N/2
from UserTable
rollback tran
如果失败,那么失败的列在另一半。 我们继续这个过程,直到找到讨厌的专栏。
比这更优雅吗?
注意:我也发现了这个问题的近似重复,但它几乎没有答案。
以下脚本将为Basetable
每个整数列创建SELECT
语句。
执行生成的SELECT
语句应该在Usertable
列。
SELECT 'PRINT '''
+ sc.Name
+ '''; SELECT MIN(CAST('
+ sc.Name
+ ' AS INTEGER)) FROM Usertable'
FROM sys.columns sc
INNER JOIN sys.types st ON st.system_type_id = sc.system_type_id
WHERE OBJECT_NAME(Object_ID) = 'BaseTable'
AND st.name = 'INT'
如果这只是手动运行的,那么根据您要插入的数据量,您可以使用OUTPUT
子句将插入的行输出到客户端。
输出的最后一行之后的行应该是有问题的行。
我采取了Lieven Keersmaekers的方法,但是扩展了它。 如果一个表具有各种数字字段长度,则此脚本将根据类型名称和精度更改Cast。 值得信赖的还是Lieven考虑这个解决方案 - 它帮了我很多。
DECLARE @tableName VARCHAR(100)
SET @tableName = 'tableName'
SELECT 'PRINT ''' + sc.NAME + '''; SELECT MIN(CAST([' + sc.NAME + '] as ' + CASE
WHEN st.NAME = 'int'
THEN 'int'
ELSE st.NAME + '(' + cast(sc.precision AS VARCHAR(5)) + ',' + cast(sc.scale AS VARCHAR(5)) + ')'
END + ')) from ' + @tableName
FROM sys.columns sc
INNER JOIN sys.types st ON st.system_type_id = sc.system_type_id
WHERE OBJECT_NAME(Object_ID) = @tableName
AND st.NAME NOT IN ('nvarchar', 'varchar', 'image', 'datetime', 'smalldatetime', 'char', 'nchar')
链接地址: http://www.djcxy.com/p/47741.html
上一篇: How to figure out which column raises an arithmetic overflow error upon insert?