【问题标题】:Conversion failed when converting the varchar value 'SAT' to data type int将 varchar 值“SAT”转换为数据类型 int 时转换失败
【发布时间】:2017-04-02 00:54:41
【问题描述】:

我有一个表ConsoleGames,其中所有列的类型都是varchar(50)。当我尝试通过使用查询修改现有数据类型来创建新表 console_games 时:

CREATE TABLE console_games
(
    game_rank integer,
    game_name varchar(1200),
    platform_name varchar(1200),
    game_year integer,
    genre varchar(200),
    publisher varchar(1200),
    na_sales float,
    eu_sales float,
    jp_sales float,
    other_sales float
)

INSERT INTO console_games
    SELECT * 
    FROM [dbo].[RAWConsoleGames]

我收到以下错误消息:

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

当我查看表中的数据时,值“SAT”位于我没有更改数据类型的列中。 'SAT' 值存在于varchar 类型的Platform 列中,我不想将类型更改为int。

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 请同时发布RAWConsoleGames的架构!
  • 可能两个表的列顺序不同...
  • @mako 没错,但我们为什么要尝试猜测?
  • @GiorgosAltanis 我们只能等他...
  • 这里是 ConsoleGames 的架构(rank varchar(5000)、name varchar(50)、Platform varchar(50)、year varchar(50)、genre varchar(200)、publisher varchar(1200) , sales varchar(50), eu_sales varchar(50), jp_sales varchar(50), other_sales varchar(50)

标签: sql-server


【解决方案1】:

显然 'SAT' 不是,也永远不会转换为 INT。

总是最好指定要插入的列...事情发生了变化

现在,如果源数据可疑,请添加try_convert()。如果转换失败,将返回一个空值

我不知道你的来源的列名,所以我替换了 SomeColN

INSERT INTO console_games
SELECT try_convert(integer      ,SomeCol1)
      ,try_convert(varchar(1200),SomeCol2)
      ,try_convert(varchar(1200),SomeCol3)
      ,try_convert(integer      ,SomeCol4)
      ,try_convert(varchar(200) ,SomeCol5)
      ,try_convert(varchar(1200),SomeCol6)
      ,try_convert(float        ,SomeCol7)
      ,try_convert(float        ,SomeCol8)
      ,try_convert(float        ,SomeCol9)
      ,try_convert(float        ,SomeCol10)
 FROM [dbo].[RAWConsoleGames]

只是为了好玩,试试吧:

Select try_convert(int,'SAT')
Select try_convert(int,'25.25')
Select try_convert(int,'25')

【讨论】:

  • 恕我不同意,try_convert 会隐藏问题,但不能解决问题(假设源表中以某种方式存在虚假数据)。
  • 但是,“始终最好指定要插入的列...事情发生变化”的建议非常重要...我自己也多次成为自己匆忙的受害者。 [不过,这个select *“技术”可以揭示模式同步问题,我猜这里没有黑/白]
  • @GiorgosAltanis 这是一个选择。一个人可能因为一个虚假/意外的价值而让整个工作失败。数据卫生是一场持久战。
  • 这也取决于工作的阶段。在 ETL 开发的早期阶段和生产、日常操作中存在不同的需求,当然您可能不希望工作因一个虚假值而失败,但您当然希望找到并报告这个虚假值也是。
  • @GiorgosAltanis 就个人而言,我首先将所有数据加载到暂存环境中。这是我们运行验证例程的地方。根据问题,我们有警告或严重故障。一个虚假的风险评级只是一个警告,而两倍的数据是一个严重的失败。正如你所说,这里没有黑白:)
【解决方案2】:

您应该始终定义要插入的列列表,还应该始终定义要从中选择的列列表。此外,我建议显式进行任何类型转换,而不是将其留给 SQL Server - 如果您自己进行,您知道您何时以及在做什么.

所以我会这样写那句话:

-- **DEFINE** the list of columns you're inserting into
INSERT INTO console_games (rank, name, Platform, year, genre, publisher, 
                           sales, eu_sales, jp_sales, other_sales) 
    -- **DEFINE** the list of columns you're selecting, and any conversions
    SELECT     
        game_rank, game_name, platform_name, 
        CAST(game_year AS VARCHAR(50)), genre,
        publisher, 
        CAST(na_sales AS VARCHAR(50)), 
        CAST(eu_sales AS VARCHAR(50)),
        CAST(jp_sales AS VARCHAR(50)),
        CAST(other_sales AS VARCHAR(50))
    FROM 
        [dbo].[RAWConsoleGames]

【讨论】:

    猜你喜欢
    • 2011-12-01
    • 2012-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多