我正在运行更新脚本来混淆数据,偶尔会遇到算术溢出错误消息,如标题中所示。正在更新的表有260k条记录,但更新脚本需要多次运行才能产生错误。尽管它非常罕见,但在修复之前我不能依赖代码,因为调试很麻烦。**偶尔**将表达式转换为数据类型的算术溢出错误int
查看其他类似的问题,通常可以通过在表格中或计算中将数据类型从INT
更改为BIGINT
来解决此问题。但是,我不明白这可能是需要的。我已经将脚本简化到了下面,因为我已经将脚本指向了一列的更新。
函数正在被更新调用,我已经在下面包含了这个函数。我怀疑,由于错误的随机性,使用NEW_ID函数可能会导致它,但是当多次运行这部分函数时,我无法重新创建错误。 NEW_ID函数不能在函数中使用,所以它被从视图中调用,也包含在下面。
更新脚本:
UPDATE dbo.Addresses
SET HouseNumber = CASE WHEN LEN(HouseNumber) > 0
THEN dbo.fn_GenerateRandomString (LEN(HouseNumber), 1, 1, 1)
ELSE HouseNumber
END
NEW_ID视图和随机串函数
CREATE VIEW dbo.vw_GetNewID
AS
SELECT NEWID() AS New_ID
CREATE FUNCTION dbo.fn_GenerateRandomString (
@stringLength int,
@upperCaseBit bit,
@lowerCaseBit bit,
@numberBit bit
)
RETURNS nvarchar(100)
AS
BEGIN
-- Sanitise string length values.
IF ISNULL(@stringLength, -1) < 0
SET @stringLength = 0
-- Generate a random string from the specified character sets.
DECLARE @string nvarchar(100) = ''
SELECT
@string += c2
FROM
(
SELECT TOP (@stringLength) c2 FROM (
SELECT c1 FROM
(
VALUES ('A'),('B'),('C')
) AS T1(c1)
WHERE @upperCaseBit = 1
UNION ALL
SELECT c1 FROM
(
VALUES ('a'),('b'),('c')
) AS T1(c1)
WHERE @lowerCaseBit = 1
SELECT c1 FROM
(
VALUES ('0'),('1'),('2'),('3'),('4'),('5'),('6'),('7'),('8'),('9')
) AS T1(c1)
WHERE @numberBit = 1
)
AS T2(c2)
ORDER BY (SELECT ABS(CHECKSUM(New_ID)) from vw_GetNewID)
) AS T2
RETURN @string
END
地址表(用于测试):
CREATE TABLE dbo.Addresses(HouseNumber nchar(32) NULL)
INSERT Addresses(HouseNumber)
VALUES ('DSjkmf jkghjsh35hjk h2jkhj3h jhf'),
('SDjfksj3548 ksjk'),
(NULL),
(''),
('2a'),
('1234567890'),
('An2b')
注意:地址表中只有7k行有输入值,即LEN(HouseNumber) > 0
。
非常感谢,这很有道理。正如你所建议的那样,我完全失去了ABS和CHECKSUM的功能,而且它很有效。我相信这将有助于减少运行时间。不幸的是,对视图的引用将需要保留,因为如果直接插入NEWID(),我会得到消息'在函数中无效使用副作用运算符newid'..再次感谢。 – Fletch
非常有帮助编辑谢谢。我用这个来代替它,它需要一半的时间!在运行新函数时,我注意到当CAST(rand * @len as INT)'返回0时,字符串长度偶尔会缩短。我改变了WHILE条件为LEN(@String)<@ stringLength',并删除了SET @ stringLength..'声明,并且运行良好。 – Fletch
@Fletch。 。 。对于编辑后的代码中的偏移量,应该是1 + cast(...)。 –