【问题标题】:Conversion failed when converting the varchar value 'NULL' to data type int. Why?将 varchar 值“NULL”转换为数据类型 int 时转换失败。为什么?
【发布时间】:2018-03-26 14:27:16
【问题描述】:

我正在尝试向我的 SQL Server 表 [master].[dbo].[TEST_concat] 添加一个名为 [Scanned] 的新列。

但是,我收到此错误:

消息 245,第 16 级,状态 1,第 2 行
将 varchar 值“NULL”转换为数据类型 int 时转换失败。

代码:

SELECT TOP (11000) 
    filer_id
    ,[filerName]
    ,[ResourceName]
    ,[UniqueIdentity]
    ,[DirID]
    ,[DirsCount]
    ,[PermCount]
    ,[RowID]
    ,[ResourceType]
    ,[ResourceFlags]
    ,[Hresult]
    ,[Details]
    ,[fsid]
    ,[Protocol]
    ,[vExport]
    ,[filerType]
    ,[Error Messages]
FROM 
    [master].[dbo].[TEST_concat]

ALTER TABLE dbo.TEST_concat
ADD [Scanned] AS
    CASE WHEN [DirID] > 0 AND [DirsCount] IS NULL 
            THEN 'in Shares table, but not SortedDirectoryTree properties'
         WHEN [DirID] > 0 AND  [DirsCount] > 0 
            THEN 'Yes'
         WHEN [DirID] IS NULL AND [DirsCount] IS NULL
            THEN 'No'
         ELSE ' ' 
    END

这是我的结果与错误消息的样子:

结果应该全部填写数千行。

【问题讨论】:

  • 你不应该为 [Scanned] 声明一个数据类型,例如 [Scanned] varchar(50) 或类似的东西
  • @RyanWilson 如果该列是计算列,则不是,否。然而,问题似乎是DirIDDirsCount 的数据类型不是int。因此,由于(糟糕的)数据选择,有人插入了文字字符串'NULL',而不是值NULL。 @ OP,找到有问题的行,更新它们的值,并修复你的数据类型。我建议使用SELECT DirID, DirsCount FROM [master].[dbo].[TEST_concat] WHERE (TRY_CONVERT(int,DirID) IS NULL AND DirID IS NOT NULL) OR (TRY_CONVERT(int, DirsCount) IS NULL AND DirsCount IS NOT NULL); 来查找有问题的行/值。
  • 看起来你有 'NULL'(作为字符串)而不是 NULL 数据
  • @larnu 对计算列很感兴趣,以前从未使用过。感谢您的信息。
  • @RyanWilson 他们非常有用,特别是如果他们是PERSISTED;因为它们也可以被索引(不是PERSISTED的计算列不能被索引)。我建议查一下。 :)

标签: sql sql-server


【解决方案1】:

将其发布为答案,只是为了扩展一点。

首先,问题似乎是DirIDDirCount 不是int 数据类型,而是varchar 或类似的数据类型。因此,作为数据选择的结果,有人插入了文字字符串值'NULL',而不是值NULL。如果您运行查询 SELECT CONVERT(int, 'NULL');,您会看到您遇到了与 OP 相同的错误。

因此,这里真正的解决方案是修复数据和数据类型。首先,您需要找到错误的值。这可以通过以下方式完成:

SELECT DirID, DirsCount
FROM [master].[dbo].[TEST_concat]
WHERE (TRY_CONVERT(int,DirID) IS NULL AND DirID IS NOT NULL)
   OR (TRY_CONVERT(int, DirsCount) IS NULL AND DirsCount IS NOT NULL);

我会先检查这些数据。如果您很高兴所有这些值都可以使用 NULL 进行更新,那么您可以执行 2 个单独的 UPDATE 语句(您可能不需要这两个语句):

UPDATE [master].[dbo].[TEST_concat]
SET DirID = NULL
WHERE TRY_CONVERT(int,DirID) IS NULL AND DirID IS NOT NULL;

UPDATE [master].[dbo].[TEST_concat]
SET DirsCount = NULL
WHERE TRY_CONVERT(int,DirsCount ) IS NULL AND DirsCount IS NOT NULL;

现在,我们或许应该看看更正数据类型。这可以通过以下方式完成:

ALTER [master].[dbo].[TEST_concat] ALTER DirID int;
ALTER [master].[dbo].[TEST_concat] ALTER DirsCount int;

现在,您可以运行您在初始帖子中的其他 ALTER 命令。

当然,这强烈假设DirIDDirsCount 应该有一个int(或十进制)值(如果是十进制,则将所有对int 的引用替换为decimal(s,p),其中sp 是您所需的比例和精度)。如果他们可以有其他值,那么那是完全不同的鱼。我想[DirsCount] > '0' 可能有不正确的结果,例如(例如)'a' > '0'。例如尝试:

SELECT CASE WHEN 'a' > '0' THEN 1 ELSE 0 END;

注意结果值是1

【讨论】:

  • 有趣的是,这已经删除了解决方案标记。 @Ruth 发生了什么变化?您尚未评论或编辑您的问题;如果您这样做,我将非常乐意扩展我的答案。
猜你喜欢
  • 2012-03-10
  • 2010-09-30
  • 2011-12-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多