【问题标题】:Error converting data type varchar to numeric in join在连接中将数据类型 varchar 转换为数字时出错
【发布时间】:2017-07-31 13:12:01
【问题描述】:

我有下一个问题

SELECT *
FROM   Assoc AS cc 
       JOIN Orders AS o    ON cc.Referencecode = o.Orderid

我收到了这个错误: 将数据类型 varchar 转换为数值时出错。

我通过添加这个子句解决了......

WHERE  ISNUMERIC (cc.Referencecode) = 1

我的问题是……这个解决方案可以吗? (我无权更改数据类型……)还是应该在联接本身中进行转换?

ps: ReferenceCode 是 varchar(50) OrderId 是十进制 (18,0)

【问题讨论】:

  • 看业务需求
  • 通常最好(性能方面)在连接本身中执行此操作。另外值得一提的是,这样您就可以从结果集中排除没有数字参考代码的记录。不确定这是否是您的意图?
  • IsNumeric() 是出了名的problematic
  • @Chicago ,有没有对你有用的答案

标签: sql-server tsql


【解决方案1】:

ISNUMERIC() 在这里可能会给您带来误报。例如,运行这些查询...

SELECT 'TRUE' WHERE ISNUMERIC('$') = 1
SELECT 'TRUE' WHERE ISNUMERIC('1e4') = 1

相反,使用以下 where 子句会更安全,该子句会删除包含除数字以外的任何内容的列。

WHERE cc.Referencecode not like '%[^0-9]%'

如果要包含小数,可以使用:

WHERE cc.Referencecode not like '%[^0-9.]%'

或用于 SQL Server 2012 / 2016

JOIN Orders AS o ON TRY_CONVERT(NUMERIC,cc.Referencecode) = o.Orderid

最后,您可以将它们都转换为 varchar,以不删除任何行。

JOIN Orders AS o ON cc.Referencecode = CAST(o.Orderid as VARCHAR(4000))

TRY_CONVERT() Reference

【讨论】:

  • 我正在挖掘“tri_convert()”,我想你偶然发现了一个非常需要的功能...... try_convert 的拼音 SQL +1,但是,你错过了 ISNUMERIC('1d4')
  • Java 还没入门哈哈
【解决方案2】:

我更喜欢这样做:-

SELECT *
FROM   Assoc AS cc 
       JOIN Orders AS o    ON cc.Referencecode = CAST(o.Orderid as Nvarchar(MAX))

【讨论】:

    【解决方案3】:

    我知道这可能需要做更多的工作,但考虑到您拥有的查询,一旦您拥有大量数据,您的扩展性就不会很好。

    但如果可能的话,我会添加一个计算列,例如

    ALTER TABLE dbo.Assoc
      ADD Referencecode_DEC AS ISNULL(TRY_CONVERT(decimal(18,0), Referencecode, 0) PERSISTED 
    

    在新列和运行查询时添加索引:

    SELECT *
    FROM   Assoc AS cc 
       JOIN Orders AS o    ON cc.Referencecode_DEC = o.Orderid
    

    它将使用正确的统计数据并且应该产生一个更好的计划

    【讨论】:

      【解决方案4】:

      CAST(Varchar AS INT) 你应该在比较之前转换它。如果是varchar。

      示例查询:

      SELECT *
      FROM   Assoc AS cc Nvarchar(MAX)
             JOIN Orders AS o    ON cc.Referencecode = CAST(o.Orderid AS Nvarchar(MAX))
      

      以这种方式进行 CAST 会导致错误。

      【讨论】:

      • 这是错误的。根据 OP,Orderid 不会导致错误
      • 我认为这个解决方案会在 CAST(o.Orderid AS NUMERIC) 上给出错误
      • 您可以将 o.Orderid 转换为 Varchar,因为根据输出 LHS 和 RHS 具有不同的数据类型。我猜 o.Orderid 是数字,而 cc.Referencecode 是 varchar。因此您可以将数字转换为 Varchar,这样比较容易。或者把 Schema 发给我,我会尽量推荐你更好的选择。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多