2013-07-04 103 views
3

这里是我的SQL查询:偶尔发生:“错误转换数据类型为nvarchar浮动”

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. 

表是这样的:

enter image description here

+0

那是你的整个表?你可能在'rssi1'中至少有一个值不是有效的浮点数.. – Blorgbeard

+0

好吧,这显然不是导致问题的数据。 'SELECT * FROM history ORDER BY id'是什么让你知道其余的数据? –

回答

5

可怕你会将它们存储在nvarchars中!我已经找到足够的1.000000000001来表达同情,但是不太喜欢这个解决方案eithe河

根据John的回答,确定您的无效记录是必要的,但您可能无法亲自处理任何事情。你提供的是一个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 
2

我上面Blorgbeard的评论表示赞同;我猜你在哪里显示CAL00022,这实际上是一个参数,所以我建议你自己编写一个小程序来解析你的历史表,寻找不同的sitename值,在rssi1中查找不会正确转换的值;

事情是这样的:(这是一个简单的工作应该找哪个坏数据所在的站点名 - 虽然你一定要去检查现有的针对网站名称自己确定哪些是不正确的实际数据

(注:这是一个有点乱,我只是打字出来很快 - 这大概可以比这做要好得多),当您不信任实数的处理在你选择的引擎这么多

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 
相关问题