我有下一个查询
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)
答案 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))
答案 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
它将使用正确的统计数据,并应产生更好的计划