- 在线时间
- 0 小时
- 专家
- 0
- UID
- 178081
- 注册时间
- 2005-5-18
- 帖子
- 2194
- 精华
- 0
- 积分
- 3724
- 离线
- 1 天
专长: .NET ,C# ,SQLServer
- 帖子
- 2194
- 体力
- 3694
- 威望
- 6
|
复杂查询的通用化
我在之前指出,所有的存储过程都是用动态SQL实现通用性的,因此,理论上它们可以用任何种类的复杂查询。下面有一个基于Northwind数据库的复杂查询例子。
- SELECT Customers.ContactName AS Customer,
- Customers.Address + ', ' + Customers.City + ', ' +
- Customers.Country AS Address,
- SUM([Order Details].UnitPrice*[Order Details].Quantity) AS
- [Total money spent]
- FROM Customers
- INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
- INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID
- WHERE Customers.Country <> 'USA' AND Customers.Country <> 'Mexico'
- GROUP BY Customers.ContactName, Customers.Address, Customers.City,
- Customers.Country
- HAVING (SUM([Order Details].UnitPrice*[Order Details].Quantity))>1000
- ORDER BY Customer DESC, Address DESC
- 返回第二个页面的分页存储调用如下:
- EXEC ProcedureName
- /* Tables */
- 'Customers
- INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID
- INNER JOIN [Order Details] ON Orders.OrderID = [Order Details].OrderID',
- /* PK */
- 'Customers.CustomerID',
- /* ORDER BY */
- 'Customers.ContactName DESC, Customers.Address DESC',
- /* PageNumber */
- 2,
- /* Page Size */
- 10,
- /* Fields */
- 'Customers.ContactName AS Customer,
- Customers.Address + '', '' + Customers.City + '', '' + Customers.Country
- AS Address,
- SUM([Order Details].UnitPrice*[Order Details].Quantity) AS [Total money spent]',
- /* Filter */
- 'Customers.Country <> ''USA'' AND Customers.Country <> ''Mexico''',
- /*Group By*/
- 'Customers.CustomerID, Customers.ContactName, Customers.Address,
- Customers.City, Customers.Country
- HAVING (SUM([Order Details].UnitPrice*[Order Details].Quantity))>1000'
复制代码
值得注意的是,在原始查询中在ORDER BY语句中使用了别名,但你最好不要在分页存储过程中这么做,因为这样的话跳过开始记录之前的行是很消耗时间的。其实有很多种方法可以用于实现,但原则是不要在一开始把所有的字段包括进去,而仅仅是包括主键列(等同于RowCount方法中的排序列),这样可以加快任务完成速度。只有在请求页中,才获得所有需要的字段。并且,在最终查询中不存在字段别名,在跳行查询中,必须提前使用索引列。
行计数(RowCount)存储过程有一个另外的问题,要实现通用化,在ORDER BY语句中只允许有一个列,这也是升序-降序方法和游标方法的问题,虽然他们可以对几个列进行排序,但是必须保证主键中只有一个字段。我猜如果用更多的动态SQL是可以解决这个问题的,但是在我看来这不是很值得。虽然这样的情况很有可能发生,但他们发生的频率不是很高。通常你可以用上面的原理也独立的分页存储过程。 |
|