數據庫中復雜的聯查+篩選條件+排序+分頁一直是比較頭疼的問題
為了模擬這個問題,首先建立兩個表
create table t_userType ( id int identity(1,1) not null primary key, name varchar(50) ) GO create table t_user ( id int identity(1,1) not null primary key, t_userTypeId int not null, name varchar(50), foreign key (t_userTypeId) references t_userType(id) ) GO
下面插入一些測試數據
在t_user這個表中,t_userTypeId字段關聯到了t_userType這個表
我們希望在查詢用戶時,同時查詢到這個用戶類型的name,可以通過聯查實現
select u.*, t.name as typeName from t_user u inner join t_userType t on t.id = u.t_userTypeId
如果聯查的表多了,就會比較復雜,所以建立一個視圖
create view view_user_andType as select u.*, t.name as typeName from t_user u inner join t_userType t on t.id = u.t_userTypeId go
這時,使用下面的語句,就能得到我們想要的結果
select * from view_user_andType
如果想提供分頁功能的話,需要這樣寫
select top 5 * from view_user_andType where id not in (select id top 0 view_user_andType)
加入條件過濾和排序
select top 5 * from view_user_andType where id>1 and id not in ( select top 0 id view_user_andType where id>1 order by id) order by id
如果每個表的聯查都寫成這樣,也是比較頭大的
所以通過一個存儲過程,封裝分頁和排序邏輯
-- 存儲過程:通用分頁 -- -- 分頁查詢某個表或視圖 -- -- 參數列表: -- srcTableName:視圖或表名 -- idColumnName:主鍵列名 -- pageSize:每頁長度(1~n) -- pageIndex:頁碼(1~n) -- condition:過濾條件 -- orderBy:排序方式,必須為查詢結果中的字段名 -- isDesc:是否倒序,可選值(true, false) -- SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO IF OBJECT_ID ( 'proc_selectByPage', 'P' ) IS NOT NULL Drop PROCEDURE [proc_selectByPage]; GO create procedure [dbo].[proc_selectByPage] @srcTableName varchar(50), @idColumnName varchar(50) = 'id', @pageSize int = 10, @pageIndex int = 1, @condition varchar(500) = '', @orderBy varchar(50), @isDesc varchar(50) = 'false' AS begin -- 參數容錯 if (@pageIndex <= 0) begin set @pageIndex = 1 end -- 組裝語句 declare @sql1 varchar(4000) set @sql1 = 'select top ' + cast (@pageSize as varchar(50)) + ' * from ' + @srcTableName + ' where (' + @idColumnName + ' not in (select top ' + cast ((@pageSize * (@pageIndex-1)) as varchar(50)) + ' ' + @idColumnName + ' from ' + @srcTableName if ( @condition <> '' ) begin set @sql1 = @sql1 + ' where ' + @condition end set @sql1 = @sql1 + ' order by ' + @orderBy if ( @isDesc = 'true' ) begin set @sql1 = @sql1 + ' desc '; end else if ( @isDesc = 'false' ) begin set @sql1 = @sql1 + ' asc '; end set @sql1 = @sql1 + ' ) ' if ( @condition <> '' ) begin set @sql1 = @sql1 + ' and ' + @condition end set @sql1 = @sql1 + ')' set @sql1 = @sql1 + ' order by ' + @orderBy if ( @isDesc = 'true' ) begin set @sql1 = @sql1 + ' desc '; end else if ( @isDesc = 'false' ) begin set @sql1 = @sql1 + ' asc '; end -- 輸出語句,並執行 print @sql1 exec(@sql1) end GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO
再實現相同的功能就可以這樣寫
exec proc_selectByPage 'view_user_andType', 'id', 3, 2, '', 'name', 'false'
可以兼容表或視圖的分頁,sqlserver2000下測試通過