尝试执行时存储过程中的语法错误

时间:2012-03-01 04:49:57

标签: sql sql-server-2008 stored-procedures

我已经为数据库中的一个操作编写了这个存储过程,但它提示有两个错误。我相当新,所以如果有人能纠正这个错误会很棒。

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

错误:

  

Msg 156,Level 15,State 1,Procedure findVersions,Line 10   关键字'SELECT'附近的语法不正确。
  Msg 156,Level 15,State 1,Procedure findVersions,Line 13
  关键字“UNION”附近的语法不正确

有什么建议吗?

更新 例如:我对查询的处理方式。我必须显示第一个查询的第一个结果,第一个结果来自第二个查询,然后是第一个查询结果中剩下的三个结果。

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

1 个答案:

答案 0 :(得分:2)

要解决“关键字'SELECT'附近的语法不正确”错误,需要使用SELECT周围的括号来编写此语句:

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

如果您使用SET设置@UnsegQuery的值,则还需要确保SELECT只会返回一个值。或者,您可以使用:

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

设置@UnsegQuery的值。在这种情况下,如果返回多个记录,@UnsegQuery将被设置为最后一条记录的值。

“关键字'UNION'附近的语法错误”正在发生,因为您无法在ORDER BY之前使用UNION。您只能在最后ORDER BY语句后使用UNION(有关详情,请参阅MSDN documentation)。

<强>更新
要从上一条评论中回答您的问题,查询最后一部分的正确语法应如下所示:

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

除第一条记录外,该语句将选择tbDatanDCG降序排列的所有记录。我不确定这有助于您解决问题,但语法是正确的。

更新2

好的,我想我明白了这个问题。您想要从表中选择所有行,但是您希望首先使用一个特定记录,将第二个不同的特定记录,然后是所有其他记录。执行此操作的一种方法是使用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]