如何确定插入时哪一列会引发算术溢出错误?

想象一下,一张桌子上有上百个不同的列。 想象一下,我想从我要将数据复制到基表的位置有一个用户数据表。 所以我写了这个简单的插入选择语句,并弹出此错误。 那么,找出哪一列会引发错误,最优雅的方法是什么?

我对解决方案的初步想法是将它包装在一个事务中,我最终将回滚并使用一种分而治之的方法:

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?

下一篇: Is there a style checker for c++?