3

这是我的 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.

表是这样的:

在此处输入图像描述

4

2 回答 2

5

当您非常不信任所选引擎中实数的处理以致将它们存储在 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
于 2013-07-05T01:54:40.253 回答
3

我同意上面 Blorgbeard 的评论;我猜你在哪里显示 CAL00022,这实际上是一个参数,所以我建议你自己写一个小程序来解析你的历史表以获取不同的站点名称值,在 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
于 2013-07-04T23:27:26.890 回答