【问题标题】:SQL Server 2008 paginating complex querySQL Server 2008 分页复杂查询
【发布时间】:2014-09-27 02:38:01
【问题描述】:

我在对以下查询进行分页时遇到问题。我已经尝试了示例here,但它给出了一些“光标”错误。

SELECT Countries.CountryID, Countries.Name as CountryName, Customers.FName, Customers.LName, Customers.EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL, Addresses.City, Addresses.State, Countries.Name,Addresses.Zip 
FROM (((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID)
WHERE (Memberships.ExpireDate > GETDATE()) AND (Addresses.EntityTypeID=200) AND (Customers.RecordStatus='A') AND (Memberships.RecordStatus='A') AND(Organizations.OrgTypeID=46 OR Organizations.OrgTypeID=55) AND (Addresses.State = 'MI ')
ORDER BY Customers.LName ASC, Organizations.OrgName, Addresses.City, Addresses.State

我需要让它每页显示 50...这个查询。

SELECT CountryID, CountryName, FName, LName, EMail, OrgName, OrgURL, City, State, CountryName,Zip
FROM (SELECT Countries.CountryID as CountryID, Countries.Name as CountryName, Customers.FName as FName, Customers.LName as LName, Customers.EMail as EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL as OrgURL, Addresses.City as City, Addresses.State as State, Countries.Name as CountryName, Addresses.Zip as Zip, ROW_NUMBER() OVER (ORDER BY Customers.LName ASC, Organizations.OrgName, Addresses.City, Addresses.State) AS RowNum
FROM (((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID)))
AS PaginatedTable
WHERE (PaginatedTable.RowNum BETWEEN 15 AND 33) AND ((Memberships.ExpireDate > GETDATE()) AND (Addresses.EntityTypeID=200) AND (Customers.RecordStatus='A') AND (Memberships.RecordStatus='A') AND(Organizations.OrgTypeID=46 OR Organizations.OrgTypeID=55) AND (Addresses.State = 'MI '))

错误是“直接执行 SQL;没有游标。”

【问题讨论】:

  • 确切的错误是什么?我在您的查询中没有看到任何光标。另外我建议你谷歌“SQL ROW_NUMBER 函数”
  • 是的,这是错误“无光标”,但我尽量使它与示例相似.. 我不习惯 MS SQL,我不特别关心它,但是这个客户使用它,所以我必须弄清楚。
  • 也许这个查询是更大脚本的一部分?因为您发布的内容不可能生成“无光标”错误。
  • 不,这是一个实际的搜索查询,我不明白为什么它会给出这个错误。 “直接执行 SQL;没有游标。SQLExecDirect 中的 SQL 状态 01000”。我根据我链接的示例更新了我的帖子以使用我尝试使用的查询
  • 这看起来不像是 SQL 错误...看起来像前端应用程序错误。

标签: sql-server pagination


【解决方案1】:

我发现括号和列定义的放置以及 orderby 存在一些问题......这是工作查询

SELECT CountryID,ExpireDate,EntityTypeID,MRecordStatus,CRecordStatus,OrgTypeID,CountryName,FName,LName,EMail,OrgName,OrgURL,City,State,CountryName,Zip
FROM (
    SELECT Countries.CountryID as CountryID, Countries.Name as CountryName, Customers.FName as FName, Customers.LName as LName, Customers.EMail as EMail, LTRIM(Organizations.OrgName) AS OrgName, Organizations.URL as OrgURL, Addresses.City as City, Memberships.ExpireDate as ExpireDate, Addresses.EntityTypeID as EntityTypeID, Memberships.RecordStatus as MRecordStatus, Organizations.OrgTypeID as OrgTypeID, Customers.RecordStatus as CRecordStatus, Addresses.State as State, Addresses.Zip as Zip, ROW_NUMBER() OVER (ORDER BY LName ASC) AS RowNum
    FROM((((Customers INNER JOIN CustomerMembershipXRef ON Customers.CustomerID = CustomerMembershipXRef.CustomerID) INNER JOIN Organizations ON Customers.OrgID = Organizations.OrgID) INNER JOIN (Countries INNER JOIN Addresses ON Countries.CountryID = Addresses.CountryID) ON Customers.CustomerID = Addresses.EntityID) INNER JOIN Memberships ON (Organizations.OrgID = Memberships.OrgID) AND (CustomerMembershipXRef.MembershipID = Memberships.MembershipID))
    WHERE ExpireDate > GETDATE() AND EntityTypeID=200 AND Customers.RecordStatus='A' AND Memberships.RecordStatus='A' AND (OrgTypeID=46 OR OrgTypeID=55) AND State = 'MI  '
)
AS PaginatedTable
WHERE PaginatedTable.RowNum BETWEEN 150 AND 200

【讨论】:

    【解决方案2】:

    在 SQL 2012 及更高版本中,有很好的 OFFSET 和 FETCH 子句作为 ORDER BY 子句的一部分。

    http://technet.microsoft.com/en-us/library/gg699618(v=sql.110).aspx

    但是,由于您使用的是 SQL 2008,因此一种解决方案是使用 ROW_NUMBER()。

    下面,我正在从冒险作品数据库中的产品表中分页记录。

    这可以转化为存储过程并由前端应用程序调用。

    真诚的

    约翰

    www.CraftyDba.com

    TSQL:

    -- PAGE CNT & ITEM CNT
    DECLARE @PAGECNT INT = 5;
    DECLARE @ITEMCNT INT = 50;
    
    -- USE COMMON TABLE EXPRESSION
    ;WITH CTE_PRODUCT AS
    (
    SELECT 
        ROW_NUMBER() OVER (ORDER BY NAME) as RID,
        *
    FROM 
        [AdventureWorks2012].[Production].[Product] P
    )
    SELECT * 
    FROM CTE_PRODUCT
    WHERE RID >= @PAGECNT * @ITEMCNT AND RID < (@PAGECNT+1) * @ITEMCNT;
    

    输出:

    嗨,b747fp,

    你测试你的答案了吗??

    我使用公用表表达式 (CTE) 的原因是由于处理 QUERY 的逻辑方式,别名不可用于 WHERE 子句。

    见下文,您的解决方案不起作用!

    约翰

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      相关资源
      最近更新 更多