Sql 偶尔发生:“将数据类型nvarchar转换为浮点时出错”

Sql 偶尔发生:“将数据类型nvarchar转换为浮点时出错”,sql,sql-server,casting,Sql,Sql Server,Casting,以下是我的SQL查询: SELECT (CAST(CAST([rssi1] AS float) AS INT))*-1, CONVERT(VARCHAR(10), [date], 110) FROM history WHERE id IN ( SELECT TOP 8 id FROM history WHERE ([siteName] = 'CAL00022') ORDER BY id DESC ) ORDER BY date ASC 大多数情况下,它工作正常

以下是我的SQL查询:

SELECT (CAST(CAST([rssi1] AS float) AS INT))*-1, CONVERT(VARCHAR(10), [date], 110)
FROM history
WHERE id IN
(
    SELECT TOP 8 id
    FROM history
    WHERE ([siteName] = 'CAL00022') 
    ORDER BY id DESC
)
ORDER BY date ASC
大多数情况下,它工作正常。有时,我会遇到这样的错误:

Server Error in '/' Application.
Error converting data type nvarchar to float.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: System.Data.SqlClient.SqlException: Error converting data type nvarchar to float.
表格如下:


我同意Blorgbeard的上述评论;我猜在显示CAL00022的地方,这实际上是一个参数,所以我建议您自己编写一个小程序来解析历史表中sitename的不同值,在rssi1中查找无法正确转换的值

类似这样的情况:这是一项简单的工作,应该可以找到存在错误数据的站点名称,不过您需要自己检查该站点名称的实际数据,以确定哪些不正确

NB:这有点乱,我只是很快就把它打出来了——它可能比这个做得更好

CREATE PROCEDURE ParseHistoryData 
AS BEGIN
  SET NOCOUNT ON;

  declare @site varchar(20);
  select distinct sitename into #tmp from history;
  create table #bad (sitename varchar(20));

  while (select COUNT(*) from #tmp) > 0 begin
    select @site = MIN(sitename) from #tmp;
    delete #tmp where sitename = @site;

    select rssi1 into #num from history where sitename = @site;
    select CAST(CAST(rssi1 AS float) AS INT) as casted into #err from #num;

    if @@ERROR <> 0 
      insert #bad values (@site);

    drop table #num;
    drop table #err;
  end 

  select sitename from #bad order by 1;
END

可怕的是,当你不信任你所选择的引擎中的实数处理,以至于你将它们存储在nvarchars中!我已经获得了足够的1.000000000001的同情,但也不太喜欢这个解决方案

根据约翰的回答,识别你的无效记录是必要的,但无论如何,你可能无法亲自做任何事情。您提供的是一个SELECT语句,它有时会失败,因此,我要解决这个问题

在尝试强制转换之前检查rssi1的值是否为数字可以避免有时出现的错误。您可以排除rssi1不是数字的记录:

SELECT
  (CAST(CAST([rssi1] AS float) AS INT))*-1,
  CONVERT(VARCHAR(10), [date], 110)
FROM history
WHERE id IN
(
    SELECT TOP 8 id
    FROM history
    WHERE ([siteName] = 'CAL00022') 
    ORDER BY id DESC
)
AND ISNUMERIC([rssi1]) = 1
ORDER BY date ASC
或者按原样呈现,每个都有自己的局限性:

SELECT
  CASE WHEN ISNUMERIC([rssi1]) = 1 THEN CAST((CAST(CAST([rssi1] as float) as int))*-1 as nvarchar) ELSE [rssi1] /* Or choose a value to default to */ END, 
  CONVERT(VARCHAR(10), [date], 110)
FROM history
WHERE id IN
(
    SELECT TOP 8 id
    FROM history
    WHERE ([siteName] = 'CAL00022') 
    ORDER BY id DESC
)
ORDER BY date ASC

那是你的整张桌子吗?rssi1中可能至少有一个值不是有效的浮点值。显然,这不是导致问题的数据。SELECT*FROM history ORDER BY id向您显示了关于其余数据的哪些信息?