An invalid floating point operation occurred when search long and latitude - sql

I use this procedure in SQL to find the near locations on Bing map by Latitude and Longitude.
The procedure returns
An invalid floating point operation occurred
when I search by this #latitude = 7025045 , #longitude = 702342
Here is my procedure:
ALTER PROCEDURE [dbo].[UppdragNearByUppdrag3]
#latitude int,
#longitude int
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT ARUppdrag.cUppdrNr AS UppdrNr, a.iLarmNorthing AS LarmKoordinatNorthing, a.iLarmEasting AS LarmKoordinatEasting
FROM Trakt AS a INNER JOIN
ARUppdrag ON a.iTraktID = ARUppdrag.iTraktID
WHERE a.iLarmNorthing <> 0 and a.iLarmEasting <> 0 And (ACOS(SIN(a.iLarmNorthing * 0.0175) * SIN(#latitude * 0.0175) + COS(a.iLarmNorthing * 0.0175) * COS(#latitude * 0.0175) *
COS(#longitude * 0.0175 - a.iLarmEasting * 0.0175)) * 3959 <= 100)
END

Cast the #longitude and #latitude to float or decimal with a large precision. Because they are INT, when they appear as the first variable in a mathematical statement, there is an implicit type cast to INT, and then there is an invalid float point operation.

Related

NPER excel function in SQL

Has anybody figured out how to use NPER excel function to SQL? Use case is that I am trying to find the remaining terms of an acct in SQL.
Fields:
Current_principalbalance - PV
Current_interestrate/100/12 - RATE
Current_paymentamount- PMT
No types in data
no FV in data
I tried:
Use NLS
go
declare #fv float
declare #rate float
declare #Pmt float
declare #k float
declare #pv float
set #fv=0
set #rate=(select (current_interest_rate/100/12) from loanacct)
set #pmt= (select amortized_payment_amount from loanacct_payment)
set #pv = (select current_principal_balance from loanacct)
set #k=1
select Log10((-#Fv * (#Rate / #k) + #Pmt)
/ (#Pmt + (#Rate / #k) * #Pv))
/ Log10(1 + #Rate) as nper
from loanacct a, loanacct_detail b, loanacct_setup c, loan_class d, loan_group e, loanacct_payment f
where a.acctrefno = b.acctrefno
and b.acctrefno = c.acctrefno
and a.loan_class2_no = d.codenum
and e.loan_group_no = a.loan_group_no
and f.acctrefno = a.acctrefno
and e.loan_group_no = 55
and a.loan_number IN (66515,67214,65980)
but now i get the error: Msg 512, Level 16, State 1, Line 9
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
Since NPER is a forumla it would be possible to implement it in SQL since the operators for a formula would almost always be supported in databases
When using "Log" in your query, the natural logarithm is considered, and nper uses the Log to base 10. Therefore the formula should be altered as
select Log10((-#Fv * (#Rate / #k) + #Pmt)
/ (#Pmt + (#Rate / #k) * #Pv))
/ Log10(1 + #Rate) as nper
Here is a test case which compares the value from excel nper function and one from the sql server database, that matches using your example..
--I have edited the datatypes to be float
declare #fv float
declare #rate float
declare #Pmt float
declare #k float
declare #pv float
set #fv=0
set #rate=15.99/100/12
set #pmt=-167.65
set #pv =1491.42
set #k=1
--In case the interests obtained at start of period then set #k as follows
--set #k = 1 + #rate
select Log10((-#Fv * (#Rate / #k) + #Pmt)
/ (#Pmt + (#Rate / #k) * #Pv))
/ Log10(1 + #Rate) as nper
+------------------+
| nper |
+------------------+
| 9.53201056406188 |
+------------------+
Excel
=NPER(15.99/100/12, -167.65,1491.42,0)
Here is a dbfiddle link
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=2f470cee443e10647f83d6e640129d51
For this use case this was my solution and it works perfect to NPER function in excel:
declare #fv float
declare #k float
set #fv=0
set #k=1
select CEILING(Log10((-#Fv * ((current_interest_rate/100/12) / #k) + -amortized_payment_amount)
/ (-amortized_payment_amount + ((current_interest_rate/100/12) / #k) * current_principal_balance))
/ Log10(1 + (current_interest_rate/100/12))) as nper

conversion from nvarchar to numeric fails

I am trying to execute this query but the following error is occurring:
Error converting data type nvarchar to numeric
this is my query :
Select Top 20 *,dbo.GetDistance(35.5,33.8, Longitude, Latitude) as Distance
From ViewBranchCoordinates
order by Distance desc
if i remove this line order by Distance desc the query run normally with no error
this is the function GetDistance
ALTER FUNCTION [dbo].[GetDistance]
(
-- Add the parameters for the function here
#Long decimal(30,24), #Lat decimal(30,24), #Long2 decimal(30,24), #Lat2 decimal(30,24)
)
--decimal(8,6), #Long)
RETURNS decimal(38,28)
AS
BEGIN
-- Declare the return variable here
DECLARE #Distance decimal(38,28)
DECLARE #valueOne decimal(30,24)
DECLARE #valueTwo decimal(30,24)
DECLARE #dLat decimal(30,24)
DECLARE #dLng decimal(30,24)
DECLARE #SectionOne decimal(30,24)
DECLARE #SectionTwo decimal(30,24)
Select #dLat = RADIANS(#Lat - #Lat2)
Select #dLng = RADIANS(#Long - #Long2)
Select #SectionOne = square(sin((#dLat)/2))
Select #SectionTwo = cos(RADIANS(#Lat)) * cos(RADIANS(#Lat2)) * square(sin(#dLng / 2))
Select #valueOne =CONVERT(decimal(30,24),#SectionOne + #SectionTwo)
Select #valueTwo = 2 * ATN2(SQRT(#valueOne), SQRT(1 - #valueOne))
Select #Distance = 6371000 * #valueTwo
RETURN #Distance
END
Any help please
I presume this will fail too?
Select Top 20 *
,dbo.GetDistance(35.5,33.8, cast (Longitude as decimal (30,24)), cast(Latitude as (30,24)) as Distance
From ViewBranchCoordinates
Your function expects data of a certain type. If your lat/long columns are nvarchar then non numeric data can be in those columns.
Search for problem data, e.g.
Select *
From ViewBranchCoordinates
Where try_cast (longitude as numeric) IS NULL
Then you need to fix the data.

SQL Server - Calculate Initial Bearing from Latitude & Longitude using GEOGRAPHY

Recently, from the help of Stackoverflow members, I got the following solution to calculate distance between two latitude and longitude points:
GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
.STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) AS [Default],
GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
.STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) / 1609.344 AS [Mi],
GEOGRAPHY::Point(DepartureAirportLatitude, DepartureAirportLongitude, 4326)
.STDistance(GEOGRAPHY::Point(ArrivalAirportLatitude, ArrivalAirportLongitude, 4326)) / 1000 AS [Km]
Is there a way, using the GEOGRAPHY feature, to calculate the initial bearing between the same data points, displaying it as a heading?
Thanks
Matthew
Thanks for your reply and the information.
After a few hours of playing around and extensive amounts of Google searching, I am using the below solution which is giving me the correct results:
DECLARE #Pi AS FLOAT
DECLARE #D2R AS FLOAT
SET #Pi = '3.14159265358979'
SET #D2R = #Pi / 180.0;
PICalculation AS
(
SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,
#D2R * DepartureAirportLatitude AS [DepartureAirportLatitude], #D2R * DepartureAirportLongitude AS [DepartureAirportLongitude],
#D2R * ArrivalAirportLatitude AS [ArrivalAirportLatitude], #D2R * ArrivalAirportLongitude AS [ArrivalAirportLongitude]
FROM RawData
),
RadiansCalculation AS
(
SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,
Radians(ArrivalAirportLatitude - DepartureAirportLatitude) AS [DLat],
Radians(ArrivalAirportLongitude - DepartureAirportLongitude) AS [DLon],
Radians(DepartureAirportLatitude) AS [RLat1],
Radians(ArrivalAirportLatitude) AS [RLat2]
FROM PICalculation
),
XYCalculation AS
(
SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,
SIN(DLon)*COS(RLat2) AS [Y],
COS(RLat1)*SIN(RLat2)-SIN(RLat1)*COS(RLat2)*COS(DLon) AS [X]
FROM RadiansCalculation
),
HeadingCalculation AS
(
SELECT FlightNo, DepartureAirportIATA, ArrivalAirportIATA,
CASE WHEN X = 0 AND Y = 0 THEN 0
ELSE CAST((DEGREES(ATN2(Y,X)) + 360) AS DECIMAL(5,1)) % 360
END AS [InitialBearing]
FROM XYCalculation
)
SELECT *
FROM DataJoin
Hopefully this solution will be useful to others who stumble across this post as well :)
Matthew
Here's a scalar function and test points that exercise it. NB: I found the source here
CREATE FUNCTION dbo.Bearing (
#point1 geography,
#point2 geography )
RETURNS float
AS
BEGIN
DECLARE #Bearing decimal(18,15)
DECLARE #Lat1 float = Radians(#point1.Lat)
DECLARE #Lat2 float = Radians(#point2.Lat)
DECLARE #dLon float = Radians(#point2.Long - #point1.Long)
IF (#point1.STEquals(#point2) = 1)
SET #Bearing = NULL
ELSE
SET #Bearing = ATN2(
sin(#dLon)*cos(#Lat2),
(cos(#Lat1)*sin(#Lat2)) - (sin(#Lat1)*cos(#Lat2)*cos(#dLon))
)
SET #Bearing = (Degrees(#Bearing) + 360) % 360
RETURN #Bearing
END
GO
DECLARE #g GEOGRAPHY = GEOGRAPHY::Point(43, 43, 4326);
DECLARE #g1 GEOGRAPHY = GEOGRAPHY::Point(42, 43, 4326);
DECLARE #g2 GEOGRAPHY = GEOGRAPHY::Point(44, 43, 4326);
DECLARE #g3 GEOGRAPHY = GEOGRAPHY::Point(43, 42, 4326);
DECLARE #g4 GEOGRAPHY = GEOGRAPHY::Point(43, 44, 4326);
SELECT dbo.[Bearing](#g, #g1),
[dbo].[Bearing](#g, #g2),
[dbo].[Bearing](#g, #g3),
[dbo].[Bearing](#g, #g4);
If doing this in T-SQL ends up being too slow, there are a couple of CLR implementations at that link as well.

Stored procedure Error converting data type nvarchar to numeric

I have this stored procedure:
ALTER PROCEDURE NearUnits
#lat float,
#lng float
AS
BEGIN
SELECT *
FROM
(
SELECT Uname, Latitude, Longitude,Info,
(
6371 * acos(
sin(#lat/57.295800) *
sin(Latitude/57.295800) +
cos(#lat/57.295800) *
cos(Latitude/57.295800) *
cos(#lng/57.295800 - Longitude / 57.295800)
)
) AS distance
FROM [dbo].[MedicalUnit]
) mytable
WHERE distance <= 20;
END;
When I execute it:
NearUnits 31.0333449532716,31.3618322632
I get this error:
Msg 8114, Level 16, State 5, Procedure NearUnits, Line 6
Error converting data type nvarchar to numeric.
Although it was working normally before !!!
any solutions??
Tray casting Latitude or Longitude:
ALTER PROCEDURE NearUnits
#lat float,
#lng float
AS
BEGIN
SELECT *
FROM
(
SELECT Uname, Latitude, Longitude,Info,
(
6371 * acos(
sin(#lat/57.295800) *
sin(CAST(Latitude AS float)/57.295800) +
cos(#lat/57.295800) *
cos(CAST(Latitude AS float)/57.295800) *
cos(#lng/57.295800 - CAST(Longitude AS float) / 57.295800)
)
) AS distance
FROM [dbo].[MedicalUnit]
) mytable
WHERE distance <= 20;
END;

How to Return Resultset with a Given Radius

I have the following SQL (SQL Server) and it works for the most part. The problem is I am really creating a square and not a true circle. My goal is to pass in a city and state which has a lat and long, then find all cities within a 100 mile radius of that lat long. The latitude and longitude are stored in the DB so all my values are there. I just need a more precise way of doing it. Here is my code thus far:
ALTER PROCEDURE [dbo].[sp_StoresByZipArea] (#zip nvarchar(5), #Radius float) AS
DECLARE #LatRange float
DECLARE #LongRange float
DECLARE #LowLatitude float
DECLARE #HighLatitude float
DECLARE #LowLongitude float
DECLARE #HighLongitude float
DECLARE #istartlat float
DECLARE #istartlong float
SELECT #iStartlat=Latitude, #iStartLong=Longitude from zipcodes where zipcode=#ZIP
SELECT #LatRange = #Radius / ((6076 / 5280) * 60)
SELECT #LongRange = #Radius / (((cos((#iStartLat * 3.141592653589 / 180)) * 6076.) / 5280.) * 60)
SELECT #LowLatitude = #istartlat - #LatRange
SELECT #HighLatitude = #istartlat + #LatRange
SELECT #LowLongitude = #istartlong - #LongRange
SELECT #HighLongitude = #istartlong + #LongRange
/** Now you can create a SQL statement which limits the recordset of cities in this manner: **/
SELECT * FROM ZipCodes
WHERE (Latitude <= #HighLatitude) AND (Latitude >= #LowLatitude) AND (Longitude >= #LowLongitude) AND (Longitude <= #HighLongitude)
I've used the great circle distance to do this in the past. The implementation below tells you the distance between two different points, which could be used to do what you are talking about:
create function dbo.GreatCircleDistance
(
#Latitude1 float,
#Longitude1 float,
#Latitude2 float,
#Longitude2 float
)
returns float
as
/*
FUNCTION: dbo.GreatCircleDistance
Computes the Great Circle distance in kilometers
between two points on the Earth using the
Haversine formula distance calculation.
Input Parameters:
#Longitude1 - Longitude in degrees of point 1
#Latitude1 - Latitude in degrees of point 1
#Longitude2 - Longitude in degrees of point 2
#Latitude2 - Latitude in degrees of point 2
*/
begin
declare #radius float
declare #lon1 float
declare #lon2 float
declare #lat1 float
declare #lat2 float
declare #a float
declare #distance float
-- Sets average radius of Earth in Kilometers
set #radius = 6371.0E
-- Convert degrees to radians
set #lon1 = radians( #Longitude1 )
set #lon2 = radians( #Longitude2 )
set #lat1 = radians( #Latitude1 )
set #lat2 = radians( #Latitude2 )
set #a = sqrt(square(sin((#lat2-#lat1)/2.0E)) +
(cos(#lat1) * cos(#lat2) * square(sin((#lon2-#lon1)/2.0E))) )
set #distance =
#radius * ( 2.0E *asin(case when 1.0E < #a then 1.0E else #a end ))
return #distance
end
Not sure if this helps, but I think there is an error here:
SELECT #LatRange = #Radius / ((6076 / 5280) * 60)
The (6076 / 5280) part will always evaluate to 1.
This functionality is available in-box for SQL Server 2012 and above. See Query Spatial Data for Nearest Neighbor:
DECLARE #g geography;
DECLARE #h geography;
-- SRID 4326 specifies the use of WGS 84 coordinate system (same as GPS)
SET #g = geography::STGeomFromText('POINT(-122.360 47.656)', 4326);
SET #h = geography::STGeomFromText('POINT(-122.34900 47.65100)', 4326);
-- Returns 995 meters
SELECT #g.STDistance(#h);