您可以尝试更新表格以去除这些字符:
UPDATE dbo.[audit]
SET UserID = REPLACE(UserID, CHAR(0), '')
WHERE CHARINDEX(CHAR(0), UserID) > 0;
但同时您也需要修复导致这些错误数据首次进入表格的问题。与此同时,可以尝试以下方法:
SELECT CONVERT(INT, REPLACE(UserID, CHAR(0), ''))
FROM dbo.[audit];
但这不是长期的解决方案。修复数据(同时也修复数据类型)。如果您无法立即修复数据类型,那么可以通过添加检查约束条件来快速找到罪犯:
ALTER TABLE dbo.[audit]
ADD CONSTRAINT do_not_allow_stupid_data
CHECK (CHARINDEX(CHAR(0), UserID) = 0);
编辑
好的,那肯定是一个四位整数,后面跟着六个 CHAR(0)。我发布的解决方法对我来说确实有效:
DECLARE @foo TABLE(UserID VARCHAR(32));
INSERT @foo SELECT 0x31353831000000000000;
SELECT CONVERT(INT, REPLACE(UserID, CHAR(0), '')) FROM @foo;
SELECT CONVERT(INT, UserID) FROM @foo;
请确认这段代码是否可以独立运行(至少第一个
SELECT
部分)。如果可以,那么您遇到的错误可能来自不同行中的非数字字符。(如果不行,则可能是某个特定 bug 未被修复的构建版本)。为了缩小范围,您可以尝试从以下查询中随机选取值,然后循环逐个字符检查:
SELECT UserID, CONVERT(VARBINARY(32), UserID)
FROM dbo.[audit]
WHERE UserID LIKE '%[^0-9]%';
那么随机选择一行,然后将输出粘贴到类似以下查询的查询中:
所以选择一行随机数据,然后将它的输出粘贴到像这样的查询语句中:
DECLARE @x VARCHAR(32), @i INT;
SET @x = CONVERT(VARCHAR(32), 0x...);
SET @i = 1;
WHILE @i <= LEN(@x)
BEGIN
PRINT RTRIM(@i) + ' = ' + RTRIM(ASCII(SUBSTRING(@x, @i, 1)))
SET @i = @i + 1;
END
在你遇到除了 CHAR(0)
之外的其他故障行之前,可能需要进行一些试错 - 因为你无法真正过滤掉包含 CHAR(0)
的行,因为它们可能包含 CHAR(0)
和 CHAR(其他内容)
。 我们所知道的是,表中可能存在以下值:
SELECT '15' + CHAR(9) + '23' + CHAR(0);
无论您是否替换了CHAR(0)
,这也无法转换为整数。
我知道您不想听,但我真的很高兴这对人们来说是痛苦的,因为现在他们有更多的战斗故事可以用来反击那些关于数据类型做出非常糟糕决策的人。