2013-04-02 41 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或主機爲您提供的任何客戶端接口),都可以使用它。

我不知道爲什麼你認爲你需要在一個代碼塊中創建三個函數,而不是單獨創建它們(因爲你的網頁顯然沒有關於批次的線索)。你只需要創建一次函數。在數據庫中創建它們之後,您可以在隨後的查詢中全天/周/月/年等參考它們。

相關問題