Eine ungültige Gleitkommaoperation ereignete sich. SQL Server 2008
-
27-10-2019 - |
Frage
Ich habe seltsames Problem mit diesem Code: Wenn ich ihn wie unten gezeigt ausführe, erhalte ich Fehler:
Eine ungültige Gleitkommaoperation ereignete sich.
Aber wenn ich den Parameter ändere @Longitude
bis -98.508730 (Beachten Sie nur, dass sich die letzte Ziffer geändert hat) Code funktioniert gut.
Der Code soll Eigenschaften auflisten @MilesRadius
rund um einen latlng Punkt.
@Latitude- und @Longitude -Parameter sind in der Tabellenadresse vom gleichen Typ wie Längengrad- und Breitengradfelder.
Was kann ich hier tun? Vielen Dank.
DECLARE @Latitude decimal (10,6);
DECLARE @Longitude decimal (10,6);
DECLARE @MilesRadius int;
SET @Latitude = 29.607654
SET @Longitude = -98.508731
SET @MilesRadius = 5
SELECT ADR.LineOne as address,
ADR.City as city,
ADR.Latitude as latitude,
ADR.Longitude as longitude,
((3959 * acos(cos(radians(@Latitude)) * cos(radians(ADR.Latitude)) * cos(radians(ADR.Longitude) - radians(@Longitude)) + sin(radians(@Latitude)) * sin(radians(ADR.Latitude))))) as distance
FROM Shared.Address ADR
WHERE ADR.Latitude IS NOT NULL AND
ADR.Longitude IS NOT NULL AND
(3959 * acos(cos(radians(@Latitude)) * cos(radians(ADR.Latitude)) * cos(radians(ADR.Longitude) - radians(@Longitude)) + sin(radians(@Latitude)) * sin(radians(ADR.Latitude)))) < @MilesRadius
ORDER BY distance
Lösung
Die einzige Funktion, die Sie verwenden, die einen Domänenfehler zurückgibt, ist ACOS
und das tritt auf, wenn der Eingang nicht im Bereich liegt -1 to +1
Sie können diesen Fall also einfach fummeln (ich nehme an, der Zwischenausdruck ist so etwas wie 1.000000000001
aufgrund von Rundungsfehlern)
SELECT ADR.LineOne as address,
ADR.City as city,
ADR.Latitude as latitude,
ADR.Longitude as longitude,
distance
FROM Shared.Address ADR
CROSS APPLY (SELECT cos(radians(@Latitude)) * cos(radians(ADR.Latitude)) * cos(radians(ADR.Longitude) - radians(@Longitude)) + sin(radians(@Latitude)) * sin(radians(ADR.Latitude))) T(ACosInput)
CROSS APPLY (SELECT ((3959 * acos(CASE WHEN ABS(ACosInput) > 1 THEN SIGN(ACosInput)*1 ELSE ACosInput END)))) T2(distance)
WHERE ADR.Latitude IS NOT NULL AND
ADR.Longitude IS NOT NULL AND
distance < @MilesRadius
ORDER BY distance