对于MS SQL,我是一个完整的新手,并且在搜索时发现了这个代码。看起来它会完全符合我的要求,即根据纬度和纬度值进行半径搜索。
但是,我一直得到:关键字'CREATE'附近的语法不正确。,这是代码的第一行。我的数据库是2008 MS SQL
以下是代码:
CREATE FUNCTION CalculateDistance
(@Longitude1 Decimal(8,5),
@Latitude1 Decimal(8,5),
@Longitude2 Decimal(8,5),
@Latitude2 Decimal(8,5))
Returns Float
AS BEGIN
Declare @Temp Float
Set @Temp = sin(@Latitude1/57.2957795130823) * sin(@Latitude2/57.2957795130823) + cos(@Latitude1/57.2957795130823) * cos(@Latitude2/57.2957795130823) * cos(@Longitude2/57.2957795130823 - @Longitude1/57.2957795130823)
if @Temp > 1
Set @Temp = 1
Else If @Temp < -1
Set @Temp = -1
Return (3958.75586574 * acos(@Temp) )
End
-- FUNCTION
CREATE FUNCTION LatitudePlusDistance(@StartLatitude Float, @Distance Float) Returns Float
AS BEGIN
Return (Select @StartLatitude + Sqrt(@Distance * @Distance / 4766.8999155991))
End
-- FUNCTION
CREATE FUNCTION LongitudePlusDistance
(@StartLongitude Float,
@StartLatitude Float,
@Distance Float)
Returns Float
AS BEGIN
Return (Select @StartLongitude + Sqrt(@Distance * @Distance / (4784.39411916406 * Cos(2 * @StartLatitude / 114.591559026165) * Cos(2 * @StartLatitude / 114.591559026165))))
End
-- ACTUAL QUERY
-- Declare some variables that we will need.
Declare @Longitude Decimal(8,5),
@Latitude Decimal(8,5),
@MinLongitude Decimal(8,5),
@MaxLongitude Decimal(8,5),
@MinLatitude Decimal(8,5),
@MaxLatitude Decimal(8,5)
-- Get the lat/long for the given id
Select @Longitude = Longitude,
@Latitude = Latitude
From qccities
Where id = '21'
-- Calculate the Max Lat/Long
Select @MaxLongitude = LongitudePlusDistance(@Longitude, @Latitude, 20),
@MaxLatitude = LatitudePlusDistance(@Latitude, 20)
-- Calculate the min lat/long
Select @MinLatitude = 2 * @Latitude - @MaxLatitude,
@MinLongitude = 2 * @Longitude - @MaxLongitude
-- The query to return all ids within a certain distance
Select id
From qccities
Where Longitude Between @MinLongitude And @MaxLongitude
And Latitude Between @MinLatitude And @MaxLatitude
And CalculateDistance(@Longitude, @Latitude, Longitude, Latitude) <= 2
知道发生了什么事吗?
谢谢!!!
编辑:非常感谢bluefeet和Aaron Bertrand指出我正确的方向!
答案 0 :(得分:3)
您还应该使用GO
或分号结束每个create语句:
另外,应该将模式添加到函数中。例如,下面使用dbo.
架构:
CREATE FUNCTION dbo.CalculateDistance
(@Longitude1 Decimal(8,5),
@Latitude1 Decimal(8,5),
@Longitude2 Decimal(8,5),
@Latitude2 Decimal(8,5))
Returns Float
AS BEGIN
Declare @Temp Float
Set @Temp = sin(@Latitude1/57.2957795130823) * sin(@Latitude2/57.2957795130823) + cos(@Latitude1/57.2957795130823) * cos(@Latitude2/57.2957795130823) * cos(@Longitude2/57.2957795130823 - @Longitude1/57.2957795130823)
if @Temp > 1
Set @Temp = 1
Else If @Temp < -1
Set @Temp = -1
Return (3958.75586574 * acos(@Temp) )
End
GO
查看正在创建的所有功能的SQL Fiddle with Demo。
答案 1 :(得分:2)
尝试不使用GO
的单一功能。 GO
不是T-SQL的一部分,它是Management Studio等客户端工具的批处理分隔符。 ColdFusion可能会将其传递给SQL Server,但它不理解GO
。因此,要么一次从ColdFusion发送一个函数(没有GO
),要么使用更好的工具来创建对象和发送查询(例如Management Studio或主机为您提供的任何客户端界面)。
我不确定为什么你认为你需要在一个代码块中创建三个函数而不是单独创建它们(因为你的网页显然没有关于批处理的线索)。您只需要创建一次函数。在数据库中创建它们之后,您可以在后续查询中全天/周/月/年等引用它们。
答案 2 :(得分:0)
您必须将多个CREATE FUNCTION
来电与GO
或;
(或两者 - 我更喜欢哪一个)分开:
CREATE FUNCTION CalculateDistance
(@Longitude1 Decimal(8,5),
@Latitude1 Decimal(8,5),
@Longitude2 Decimal(8,5),
@Latitude2 Decimal(8,5))
Returns Float
AS BEGIN
Declare @Temp Float
Set @Temp = sin(@Latitude1/57.2957795130823) * sin(@Latitude2/57.2957795130823) + cos(@Latitude1/57.2957795130823) * cos(@Latitude2/57.2957795130823) * cos(@Longitude2/57.2957795130823 - @Longitude1/57.2957795130823)
if @Temp > 1
Set @Temp = 1
Else If @Temp < -1
Set @Temp = -1
Return (3958.75586574 * acos(@Temp) )
End;
GO
-- FUNCTION
CREATE FUNCTION LatitudePlusDistance(@StartLatitude Float, @Distance Float) Returns Float
AS BEGIN
Return (Select @StartLatitude + Sqrt(@Distance * @Distance / 4766.8999155991))
End
-- FUNCTION
CREATE FUNCTION LongitudePlusDistance
(@StartLongitude Float,
@StartLatitude Float,
@Distance Float)
Returns Float
AS BEGIN
Return (Select @StartLongitude + Sqrt(@Distance * @Distance / (4784.39411916406 * Cos(2 * @StartLatitude / 114.591559026165) * Cos(2 * @StartLatitude / 114.591559026165))))
End;
GO
答案 3 :(得分:0)
该SQL中有许多CREATE
个语句。必须将GO
放在语句之间,才能将它们分成批次。
SSMS中的一半消息显示了这一点:
'CREATE FUNCTION'必须是查询批处理中的第一个语句。
所以要解决:
CREATE FUNCTION CalculateDistance
(@Longitude1 Decimal(8,5),
@Latitude1 Decimal(8,5),
@Longitude2 Decimal(8,5),
@Latitude2 Decimal(8,5))
Returns Float
AS BEGIN
...
END
GO
CREATE FUNCTION LatitudePlusDistance(@StartLatitude Float, @Distance Float) Returns Float
AS BEGIN
Return (Select @StartLatitude + Sqrt(@Distance * @Distance / 4766.8999155991))
End
GO
CREATE FUNCTION... etc