除非同时指定了 TOP 或 FOR XML,否则 ORDER BY 子句无效

问题描述 投票:0回答:6

我得到“ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP 或 FOR XML。”以下代码出错。我最初有两个表:ADSAREAS 和 CATEGORIES。当我删除 CATEGORIES 表时,我开始收到此错误。

    Select Case SIDX  
     Case "ID" : SQLCONT1 = " AdsAreasID"
     Case "Page" : SQLCONT1 = " AdsAreasName"
     Case Else : SQLCONT1 = " AdsAreasID"  
End Select   
Select Case SORD  
     Case "asc" : SQLCONT2 = " ASC"
     Case "desc" : SQLCONT2 = " DESC"
     Case Else : SQLCONT2 = " ASC"  
End Select   
''# search feature --->
Select Case SEARCHFIELD  
     Case "ID" : SQLSFIELD = "AND AdsAreasID"
     Case "Ads Areas" : SQLSFIELD = "AND AdsAreasName"
     Case Else : SQLSFIELD = ""  
End Select  
Select Case SEARCHOPER  
     Case "eq" : SQLSOPER = " = " & SEARCHSTRING
     Case "ne" : SQLSOPER = " <> " & SEARCHSTRING
     Case "lt" : SQLSOPER = " <" & SEARCHSTRING
     Case "le" : SQLSOPER = " <= " & SEARCHSTRING    
     Case "gt" : SQLSOPER = " >" & SEARCHSTRING
     Case "ge" : SQLSOPER = " >= " & SEARCHSTRING
     Case "bw" : SQLSOPER = " LIKE '" & SEARCHSTRING & "%' "
     Case "ew" : SQLSOPER = " LIKE '%" & SEARCHSTRING & "' "
     Case "cn" : SQLSOPER = " LIKE '%" & SEARCHSTRING & "%' "
     Case Else : SQLSOPER = ""  
End Select  
''# search feature --->

SQL = "SELECT * FROM ( SELECT A.AdsAreasID, A.AdsAreasName, ROW_NUMBER() OVER (ORDER BY A.AdsAreasID) As Row"
SQL = SQL & " FROM ADSAREAS A"
SQL = SQL & " WHERE Row > ("& RecordsPageSize - RecordsPerPage &") AND Row <= ("& RecordsPageSize &") ORDER BY" & SQLCONT1 & SQLCONT2
Set objXML = objConn.Execute(SQL)
sql-server asp-classic
6个回答
11
投票

您在重写时将 ORDER BY 子句移至内部查询。在 WHERE 子句后添加括号(和标识符),以便 ORDER BY 适用于外部 SELECT。

SQL = "SELECT * FROM ( SELECT A.AdsAreasID, A.AdsAreasName, ROW_NUMBER() OVER (ORDER BY A.AdsAreasID) As Row"
SQL = SQL & " FROM ADSAREAS A"
SQL = SQL & " WHERE Row > ("& RecordsPageSize - RecordsPerPage &") AND Row <= ("& RecordsPageSize &")) inner ORDER BY" & SQLCONT1 & SQLCONT2

8
投票

除了接受的答案之外,您可以简单地使用

TOP (100) PERCENT

例如:

SELECT table1Col, ...
FROM   yourTABLE1
JOIN   -- doesn't matter what join you use
( SELECT TOP (100) PERCENT
         table2Col, ...
  FROM   yourTABLE2
  ORDER BY table2Col,....
) AS TB2 ON yourTABLE1.Col = TB2.Col 

现在你的

ORDER
可以工作了


2
投票

如果您查看代码生成的查询,将会有所帮助:

SELECT * 
FROM (
  SELECT 
    A.AdsAreasID, 
    A.AdsAreasName, 
    ROW_NUMBER() OVER (ORDER BY A.AdsAreasID) As Row
  FROM ADSAREAS A
  WHERE 
    Row > ("& RecordsPageSize - RecordsPerPage &") 
    AND Row <= ("& RecordsPageSize &")
  ORDER BY" & SQLCONT1 & SQLCONT2

请注意,您缺少一个结束

)
字符,并且如果将其放在末尾,则
ORDER BY
将位于内部查询中,而不是外部查询中,这是无效的。您最好完全删除外部查询。它没有任何作用。

尽管以这种方式构建查询存在 SQL 注入问题。


2
投票

除了上面接受的答案之外,书《Inside Microsoft SQL Server 2008:T-SQL 编程》第 1 章第 4 页中还提到:

请注意,该错误并没有说明完全禁止 ORDER BY;而是说明完全不允许使用 ORDER BY。相反,它指示了一些允许的例外情况 - 当还指定了 TOP 或 FOR XML 时。请记住,TOP 和 FOR XML 都是 T-SQL 扩展,而不是标准 SQL 元素。 TOP 和 ORDER BY 或 ORDER BY 和 FOR XML 是结果集规范的一部分,而单独的 ORDER BY 则不是,并且仅指定表示的细节。因此,视图定义中允许使用 TOP 和 ORDER BY 或 ORDER BY 和 FOR XML,而单独使用 ORDER BY 则不允许。


0
投票


0
投票

SELECT * into tmpToUatOrdered FROM tmpToUatScript ORDER BY MAX(CASE WHEN parent_id IS NULL THEN UPDATED_DATE END) OVER (PARTITION BY COALESCE(parent_id, id)) DESC, parent_id, UPDATED_DATE DESC

© www.soinside.com 2019 - 2024. All rights reserved.