SQL: 无法在复杂查询中将 nvarchar 转换为数字

SQL: Cannot convert nvarchar to numeric in complex query

我需要在我的数据库中从当前用户位置获取最近的机场 table。我找到了这个公式:https://de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7

所以上面link中描述的公式和我现在的情况有一些不同:示例在MySQL,我使用的是MS SQL(不是一个问题,我猜)。 latlon 被认为是具有 numeric 数据类型的数据库列,但由于某种原因,数据库 table 是用两个对应的 varchar 类型列创建的.

我的问题是:当我想使用 ORDER BY 子句时,它会抛出 Error converting data type nvarchar to numeric,没有它,它会起作用。我对哪些垃圾作为字符串插入并迁移了它进行了一些研究,以便我只有一些空值。

我不能全部拿走,因为我只需要一个。但是,如果我在没有 ORDER BY 的情况下执行 TOP 1,我不会得到 任何 机场而不是最近的机场。有谁知道如何修复查询?

提前致谢!

SELECT TOP 1
  temp.Distance
FROM (
  SELECT
    (
      3956 * 2 * ASIN(
          SQRT(
              POWER(
                  SIN((53.6349994 - abs(CAST(latitude_deg AS numeric))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(CAST(latitude_deg AS numeric)) * pi()/180) * POWER(SIN((10.0117336 - CAST(longitude_deg AS numeric)) * pi()/180 / 2), 2) ))) AS Distance
  FROM Airport_Airports
  WHERE
    isnumeric(longitude_deg) = 1 AND isnumeric(latitude_deg) = 1 AND
    longitude_deg LIKE '%[^0-9.]%' AND latitude_deg LIKE '%[^0-9.]%'
) AS temp
WHERE
  temp.Distance < 50000
Order BY
  temp.Distance

首先,这个逻辑说不通:

WHERE isnumeric(longitude_deg) = 1 AND
      isnumeric(latitude_deg) = 1 AND
      longitude_deg LIKE '%[^0-9.]%' AND
      latitude_deg LIKE '%[^0-9.]%'

like 正在寻找 非数字 字符。我想你打算:

WHERE isnumeric(longitude_deg) = 1 AND
      isnumeric(latitude_deg) = 1 AND
      longitude_deg NOT LIKE '%[^0-9.]%' AND
      latitude_deg NOT LIKE '%[^0-9.]%'

这确保值是数字。

您的问题的解决方案——至少在 SQL Server 2012+ 中——是使用 try_convert()try_cast():

  (3956 * 2 * ASIN(
      SQRT(
          POWER(
              SIN((53.6349994 - abs(try_convert(numeric, latitude_deg))) * pi() / 180 / 2), 2) + COS(53.6349994 * pi()/180) * COS(abs(try_convert(numeric, latitude_deg)) * pi()/180) * POWER(SIN((10.0117336 - try_convert(numeric, longitude_deg)) * pi()/180 / 2), 2) ))) AS Distance

这将防止任何转换错误。

你不应该只使用 numeric。使用浮点表示或带小数位的东西,比如 numeric(20, 10).

order by 出现这种情况的原因是 SQL 优化器。您显然有一些 lat/long 值无法正确转换为 numeric。 SQL 服务器允许自己重新安排操作,因此转换可能会在 之前 通过 where 子句进行过滤。这是整体查询优化的一部分。