在连接中将数据类型varchar转换为数字时出错

时间:2017-07-31 13:12:02

标签: sql-server tsql

我有下一个查询

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)

4 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我更愿意这样做: -

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

答案 2 :(得分:0)

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以这种方式给你带来错误。

答案 3 :(得分:0)

我知道这可能会有更多的工作,但是如果您拥有大量数据,那么根据您的查询,您将无法很好地扩展。

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

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

它将使用正确的统计数据,并应产生更好的计划