[英]SQL: Cannot convert nvarchar to numeric in complex query
I need to get the nearest airport in my database table from the current users position. 我需要从当前用户位置获取数据库表中最近的机场。 I found this formula: https://de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7 我找到了这个公式: https : //de.scribd.com/presentation/2569355/Geo-Distance-Search-with-MySQL#page=7
So there are a few differences between the formula described in the link above and my current situation: The example was in MySQL, I'm using MS SQL (not a problem, I guess). 因此,上面的链接中描述的公式与我的当前状态之间存在一些差异:该示例在MySQL中,我使用的是MS SQL(我想这不是问题)。 lat
and lon
are considered to be database columns with numeric
data type, but for some reason the database table was created with two corresponding columns of type varchar
. lat
和lon
被认为是具有numeric
数据类型的数据库列,但是由于某种原因,数据库表是使用两个对应的varchar
类型的列创建的。
My problem is: When I want to use an ORDER BY
clause, it throws Error converting data type nvarchar to numeric
, without it, it works. 我的问题是:当我想使用ORDER BY
子句时, Error converting data type nvarchar to numeric
,没有它,它将起作用。 I did some research on what rubbish was inserted as string and migrated it so that I just have some empty values. 我对将什么垃圾作为字符串插入并进行了迁移进行了一些研究,以便获得一些空值。
I can't take all because I only need one. 我不能全部拿走,因为我只需要一个。 But if I do TOP 1
without ORDER BY
I don't get any airport rather than the nearest airport. 但是,如果我在没有ORDER BY
情况下进行TOP 1
,则我不会到达任何机场,而不是最近的机场。 Does anyone know how to fix the query? 有人知道如何解决查询吗?
Thanks in advance! 提前致谢!
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
First, this logic doesn't make sense: 首先,这种逻辑没有意义:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg LIKE '%[^0-9.]%' AND
latitude_deg LIKE '%[^0-9.]%'
The like
is looking for non-numeric characters. like
正在寻找非数字字符。 I think you intend: 我认为您打算:
WHERE isnumeric(longitude_deg) = 1 AND
isnumeric(latitude_deg) = 1 AND
longitude_deg NOT LIKE '%[^0-9.]%' AND
latitude_deg NOT LIKE '%[^0-9.]%'
This ensures that the values are numeric. 这样可以确保值是数字。
The solution to your problem -- at least in SQL Server 2012+ -- is to use try_convert()
or try_cast()
: 解决问题的方法(至少在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
This will prevent any conversion errors. 这样可以防止任何转换错误。
You shouldn't use just numeric
. 您不应该只使用numeric
。 Use either a floating point representation or something with decimal places, say numeric(20, 10)
. 使用浮点表示形式或带小数位的内容,例如numeric(20, 10)
。
The reason this occurs with the order by
is because of the SQL optimizer. order by
发生的原因是由于SQL优化器。 You clearly have some lat/long values that do not convert correctly to a numeric
. 显然,您有一些经/纬度值无法正确转换为numeric
。 SQL Server allows itself to re-arrange operations, so the conversion might take place before the filtering by the where
clause. SQL Server允许自己重新安排操作,因此转换可能发生在 where
子句筛选之前 。 This is part of the overall query optimization. 这是整体查询优化的一部分。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.