2012-03-01 50 views
1

我已經爲數據庫中的一項操作編寫了此存儲過程,但它提示出現兩個錯誤。我相當新,最重要的是,如果有人能糾正這個錯誤,那將會很棒。嘗試執行時存儲過程中的語法錯誤

CREATE PROCEDURE findVersions 
    @seg nvarchar(255), 
    @str nvarchar(255) 
AS 

    DECLARE @UnsegQuery AS nvarchar(255) 

    SET @UnsegQuery = SELECT DISTINCT UnsegmQuery 
         FROM tbData 
        WHERE SegQuery = @seg 

    SELECT TOP 1 Strategy, Versions, CGNum 
    FROM tbData 
    WHERE Strategy = @str 
    AND SegQuery = @seg 
ORDER BY CGnum DESC 
    UNION 
    SELECT TOP 1 Strategy, Versions 
    FROM tbData 
    WHERE Strategy = 'BF' 
    AND UnsegmQuery = @UnsegQuery 
    UNION 
    SELECT Strategy, Versions 
    FROM (SELECT ROW_NUMBER() OVER (ORDER BY nDCG DESC) AS rownumber 
      FROM tbData) AS foo 
    WHERE rownumber > 1 

錯誤:

消息156,級別15,狀態1,過程findVersions,行中的關鍵字10
附近有語法錯誤 'SELECT'。
消息156,級別15,狀態1,過程findVersions,行中的關鍵字 '聯盟'

任何建議近13
語法不正確?

更新 例如:我與查詢有什麼關係。我必須顯示第一個查詢的第一個結果,第二個查詢的第一個結果以及第一個查詢結果的剩餘三個結果。

1st class: (has 4 student) 

Tom (Has highest score) 
Rex (Hss second highest score) 
Rambo (HAs 3rd highest score) 
Betty (Has least score) 

2nd class: (has 1 student) 

Spooky (Has the highest score) 

Required result order in DataControl: 

Tom 
Spooky 
Rex 
Rambo 
Betty 
+0

這看起來並不完整 - 「@ UnsegQuery」已聲明並設置,但從未使用過。 UNION中的第三個查詢不正確,因爲它是獨立的。打破'聯盟',並逐漸增加以確定你的問題是什麼。 – 2012-03-01 05:08:17

+0

嘗試在子查詢周圍放置括號('SET @UnsegQuery ='後面)。 – 2012-03-01 05:09:18

+0

@JohnPick:請參閱[TSQL:SET vs SELECT](http://stackoverflow.com/questions/3945361/t-sql-set-verus-select-when-assigning-variables) – 2012-03-01 05:09:46

回答

2

爲了解決錯誤「關鍵字‘SELECT’附近有語法錯誤」,這句話需要使用SELECT周圍括號寫:如果你使用SET設置的值

SET @UnsegQuery = (SELECT DISTINCT UnsegmQuery FROM tbData WHERE SegQuery = @seg) 

@UnsegQuery,您還需要確定SELECT只會返回一個值。或者,您可以使用:

SELECT DISTINCT @UnsegQuery = UnsegmQuery FROM tbData WHERE SegQuery = @seg 

設置值爲@UnsegQuery。在這種情況下,如果返回多條記錄,則@UnsegQuery將設置爲最後一條記錄的值。

由於在UNION之前不能使用ORDER BY,所以發生「關鍵字'UNION'附近的語法錯誤」錯誤。在最後的UNION聲明之後,您只能使用ORDER BY(有關更多信息,請參閱MSDN documentation)。

UPDATE
要從最後的評論回答你的問題,對於查詢的最後一部分的正確語法應該是這個樣子:

SELECT foo.Strategy, foo.Versions 
FROM (
    SELECT Strategy, Versions, ROW_NUMBER() OVER (ORDER BY nDCG DESC) AS [rownumber] 
    FROM tbData) foo 
WHERE foo.rownumber > 1 

該聲明將選擇從tbData下令所有記錄通過nDCG降序除第一條記錄。我不確定這有助於你解決問題,但語法是正確的。

更新2

OK,我想我明白這個問題。你想從表格中選擇所有的行,但你希望一個特定的記錄是第一個,一個不同的特定記錄是第二個,然後是其餘的。一種做法是使用CASE WHEN語句將值分配給所需的第一行,所需的第二行,然後按該值進行排序。例如:

DECLARE @myTable TABLE([ID] INT, [Student] VARCHAR(10)) 
INSERT INTO @myTable VALUES(1, 'Tom') 
INSERT INTO @myTable VALUES(2, 'Spooky') 
INSERT INTO @myTable VALUES(3, 'Rex') 
INSERT INTO @myTable VALUES(4, 'Rambo') 
INSERT INTO @myTable VALUES(5, 'Betty') 
DECLARE @firstID INT, @secondID INT 
SET @firstID = 2 
SET @secondID = 4 

SELECT * 
FROM @myTable 
ORDER BY 
    CASE 
     WHEN [ID] = @firstID THEN 1 
     WHEN [ID] = @secondID THEN 2 
     ELSE 3 
    END, 
    [ID] 
+0

SET'現在可以工作,但是你能否推薦一種解決第二個錯誤的方法?我應該怎麼做才能在第一個查詢中檢索最上面的結果呢? – user1240679 2012-03-01 05:16:04

+0

如果我從第一個查詢中刪除ORDER BY,奇怪的是它開始顯示:最後一個查詢的錯誤:'無效的列名'Strategy'。 列名'QuotedVersions'。' – user1240679 2012-03-01 05:19:48

+0

更新了問題,併爲我正在嘗試做的事添加了一個示例 – user1240679 2012-03-01 05:22:17