2013-04-02 39 views
4

当涉及到MS SQL并且在搜索过程中发现此代码时,我是一个完整的新手。它看起来就像我想要的那样,它是基于纬度和纬度值进行半径搜索的。创建函数时关键字'CREATE'附近的语法不正确

但是,我不断收到:关键字'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

除了使用'GO'分隔批次外,[请使用'dbo.'前缀创建/引用对象,*尤其是*函数](http:// sqlblog。COM /博客/ aaron_bertrand /存档/ 2009/10/11 /坏习惯,对开球避开最架构prefix.aspx)。 –

+0

@AaronBertrand hello亚伦,我的服务器在共享环境中,MS SQL数据库表都不在dbo中,而是它们是user21587。所以我的表将是user21587.qccities这是否有所作为?我确实尝试了我的前缀和dbo。前缀,两者仍然给我错误,现在它说:'去'附近的语法不正确。 – Jennifer

+0

你究竟在哪里运行这段代码?你是否尝试过分别运行每个“CREATE FUNCTION”? –

回答

2

你也应该有一个GO或分号结束每个创建语句:

此外,应架构添加到函数。例如下面的使用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

+0

你的小提琴仍然没有'dbo'。 –

+0

@JonEgerton你是对的,我正在更新我的答案,包括缺少'GO'并建议使用'dbo.'或某个模式。 – Taryn

+0

@bluefeet感谢您的回复。然后,我发现sql小提琴正在工作,但是,当我将相同的代码添加到我的页面时,我现在得到:'go'附近的语法不正确我的功能和实际查询在同一个sql块中做错了吗?要么?也许我不是100%清楚函数的工作方式:( – Jennifer

0

你要多CREATE FUNCTION电话与GO OR ;分离(或两者 - 我更喜欢哪一个):

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 
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 
2

尝试一个单一的功能,而不GOGO不是T-SQL的一部分,它是Management Studio等客户端工具的批处理分隔符。 ColdFusion可能会将其传递给SQL Server,但它不了解GO。因此,无论是从ColdFusion(不包括GO)一次发送一个函数,还是使用更好的工具创建对象并发送查询(例如,Management Studio或主机为您提供的任何客户端接口),都可以使用它。

我不知道为什么你认为你需要在一个代码块中创建三个函数,而不是单独创建它们(因为你的网页显然没有关于批次的线索)。你只需要创建一次函数。在数据库中创建它们之后,您可以在随后的查询中全天/周/月/年等参考它们。

相关问题