/**//// <summary>
/// MS SQLSERVER 分頁SQL語句生成器,同樣適用於ACCESS數據庫(edit:2008.3.29)
/// </summary>
/// <param name="strSQLInfo">原始SQL語句</param>
/// <param name="strWhere">在分頁前要替換的字符串,用於分頁前的篩選</param>
/// <param name="PageSize">頁大小</param>
/// <param name="PageNumber">頁碼</param>
/// <param name="AllCount">記錄總數</param>
/// <returns>生成SQL分頁語句</returns>
private static string MakePageSQLStringByMSSQL(string strSQLInfo,string strWhere,int PageSize,int PageNumber,int AllCount)
...{
分頁位置分析#region 分頁位置分析
string strSQLType=string.Empty ;
if(AllCount!=0)
...{
if(PageNumber==1) //首頁
...{
strSQLType="First";
}
else if(PageSize*PageNumber>AllCount) //最後的頁 @@LeftSize
...{
PageSize=AllCount-PageSize*(PageNumber-1);
strSQLType="Last";
}
else //中間頁
...{
strSQLType="Mid";
}
}
else if(AllCount<0) //特殊處理 dth,2006.10.19
...{
strSQLType="First";
}
else
...{
strSQLType="Count";
}
#endregion
SQL 複雜度分析#region SQL 複雜度分析
//SQL 複雜度分析 開始
bool SqlFlag=true;//簡單SQL標記
string TestSQL=strSQLInfo.ToUpper ();
int n=TestSQL.IndexOf ("SELECT ",0);
n=TestSQL.IndexOf ("SELECT ",n+7);
if(n==-1)
...{
//可能是簡單的查詢,再次處理
n=TestSQL.IndexOf (" JOIN ",n+7);
if(n!=-1) SqlFlag=false;
else
...{
//判斷From 謂詞情況
n=TestSQL.IndexOf("FROM ",9);
if(n==-1) return "";
//計算 WHERE 謂詞的位置
int m=TestSQL.IndexOf ("WHERE ",n+5);
// 如果沒有WHERE 謂詞
if(m==-1) m=TestSQL.IndexOf ("ORDER BY ",n+5);
//如果沒有ORDER BY 謂詞,那麼無法排序,退出;
if(m==-1)
throw new Exception ("查詢語句分析:當前沒有爲分頁查詢指定排序字段!請適當修改SQL語句。 "+strSQLInfo);
string strTableName=TestSQL.Substring (n,m-n);
//表名中有 , 號表示是多表查詢
if(strTableName.IndexOf (",")!=-1)
SqlFlag=false;
}
}
else
...{
//有子查詢;
SqlFlag=false;
}
//SQL 複雜度分析 結束
#endregion
排序語法分析#region 排序語法分析
//排序語法分析 開始
int iOrderAt=strSQLInfo.ToLower ().LastIndexOf ("order by ");
//如果沒有ORDER BY 謂詞,那麼無法排序分頁,退出;
if(iOrderAt==-1)
throw new Exception ("查詢語句分析:當前沒有爲分頁查詢指定排序字段!請適當修改SQL語句。 "+strSQLInfo);
string strOrder=strSQLInfo.Substring (iOrderAt+9);
strSQLInfo=strSQLInfo.Substring(0,iOrderAt);
string[] strArrOrder=strOrder.Split (new char []...{','});
for(int i=0;i<strArrOrder.Length ;i++)
...{
string[] strArrTemp=(strArrOrder[i].Trim ()+" ").Split (new char[]...{' '});
//壓縮多餘空格
for(int j=1;j<strArrTemp.Length ;j++)
...{
if(strArrTemp[j].Trim ()=="")
...{
continue;
}
else
...{
strArrTemp[1]=strArrTemp[j];
if(j >1 ) strArrTemp[j]="";
break;
}
}
//判斷字段的排序類型
switch(strArrTemp[1].Trim ().ToUpper ())
...{
case "DESC":
strArrTemp[1]="ASC";
break;
case "ASC":
strArrTemp[1]="DESC";
break;
default:
//未指定排序類型,默認爲降序
strArrTemp[1]="DESC";
break;
}
//消除排序字段對象限定符
if(strArrTemp[0].IndexOf (".")!=-1)
strArrTemp[0]=strArrTemp[0].Substring (strArrTemp[0].IndexOf (".")+1);
strArrOrder[i]=string.Join (" ",strArrTemp);
}
//生成反向排序語句
string strNewOrder=string.Join (",",strArrOrder).Trim ();
strOrder=strNewOrder.Replace ("ASC","ASC0").Replace ("DESC","ASC").Replace ("ASC0","DESC");
//排序語法分析結束
#endregion
構造分頁查詢#region 構造分頁查詢
string SQL=string.Empty ;
if(!SqlFlag)
...{
//複雜查詢處理
switch(strSQLType.ToUpper ())
...{
case "FIRST":
SQL="Select Top @@PageSize * FROM ( " +strSQLInfo+
" ) P_T0 @@Where ORDER BY "+strOrder;
break;
case "MID":
SQL=@"SELECT Top @@PageSize * FROM
(SELECT Top @@PageSize * FROM
(
SELECT Top @@Page_Size_Number * FROM (";
SQL+=" "+strSQLInfo+" ) P_T0 @@Where ORDER BY "+strOrder+" ";
SQL+=@") P_T1
ORDER BY "+ strNewOrder +") P_T2 "+
"ORDER BY "+strOrder;
break;
case "LAST":
SQL=@"SELECT * FROM (
Select Top @@LeftSize * FROM ("+" "+strSQLInfo+" ";
SQL+=" ) P_T0 @@Where ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "COUNT":
SQL="Select COUNT(*) FROM ( " +strSQLInfo+" ) P_Count @@Where";
break;
default:
SQL=strSQLInfo+strOrder;//還原
break;
}
}
else
...{
//簡單查詢處理
switch(strSQLType.ToUpper ())
...{
case "FIRST":
SQL=strSQLInfo.ToUpper().Replace ("SELECT ","SELECT TOP @@PageSize ");
SQL+=" @@Where ORDER BY "+strOrder;
break;
case "MID":
string strRep=@"SELECT Top @@PageSize * FROM
(SELECT Top @@PageSize * FROM
(
SELECT Top @@Page_Size_Number ";
SQL=strSQLInfo.ToUpper().Replace ("SELECT ",strRep);
SQL+=" @@Where ORDER BY "+strOrder;
SQL+=" ) P_T0 ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "LAST":
string strRep2=@"SELECT * FROM (
Select Top @@LeftSize ";
SQL=strSQLInfo.ToUpper().Replace ("SELECT ",strRep2);
SQL+=" @@Where ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "COUNT":
SQL="Select COUNT(*) FROM ( " +strSQLInfo+" @@Where) P_Count ";//edit 2008.3.29
break;
default:
SQL=strSQLInfo+strOrder;//還原
break;
}
}
//執行分頁參數替換
SQL=SQL.Replace ("@@PageSize",PageSize.ToString ())
.Replace ("@@Page_Size_Number",Convert.ToString (PageSize * PageNumber))
.Replace ("@@LeftSize",PageSize.ToString ());//
//.Replace ("@@Where",strWhere);
//針對用戶的額外條件處理:
if(strWhere!="" && strWhere.ToUpper ().Trim ().StartsWith ("WHERE "))
...{
throw new Exception ("分頁額外查詢條件不能帶Where謂詞!");
}
if(!SqlFlag)
...{
if(strWhere!="") strWhere=" Where "+strWhere;
SQL=SQL.Replace ("@@Where",strWhere);
}
else
...{
if(strWhere!="") strWhere=" And ("+strWhere+")";
SQL=SQL.Replace ("@@Where",strWhere);
}
return SQL;
#endregion
}
/// MS SQLSERVER 分頁SQL語句生成器,同樣適用於ACCESS數據庫(edit:2008.3.29)
/// </summary>
/// <param name="strSQLInfo">原始SQL語句</param>
/// <param name="strWhere">在分頁前要替換的字符串,用於分頁前的篩選</param>
/// <param name="PageSize">頁大小</param>
/// <param name="PageNumber">頁碼</param>
/// <param name="AllCount">記錄總數</param>
/// <returns>生成SQL分頁語句</returns>
private static string MakePageSQLStringByMSSQL(string strSQLInfo,string strWhere,int PageSize,int PageNumber,int AllCount)
...{
分頁位置分析#region 分頁位置分析
string strSQLType=string.Empty ;
if(AllCount!=0)
...{
if(PageNumber==1) //首頁
...{
strSQLType="First";
}
else if(PageSize*PageNumber>AllCount) //最後的頁 @@LeftSize
...{
PageSize=AllCount-PageSize*(PageNumber-1);
strSQLType="Last";
}
else //中間頁
...{
strSQLType="Mid";
}
}
else if(AllCount<0) //特殊處理 dth,2006.10.19
...{
strSQLType="First";
}
else
...{
strSQLType="Count";
}
#endregion
SQL 複雜度分析#region SQL 複雜度分析
//SQL 複雜度分析 開始
bool SqlFlag=true;//簡單SQL標記
string TestSQL=strSQLInfo.ToUpper ();
int n=TestSQL.IndexOf ("SELECT ",0);
n=TestSQL.IndexOf ("SELECT ",n+7);
if(n==-1)
...{
//可能是簡單的查詢,再次處理
n=TestSQL.IndexOf (" JOIN ",n+7);
if(n!=-1) SqlFlag=false;
else
...{
//判斷From 謂詞情況
n=TestSQL.IndexOf("FROM ",9);
if(n==-1) return "";
//計算 WHERE 謂詞的位置
int m=TestSQL.IndexOf ("WHERE ",n+5);
// 如果沒有WHERE 謂詞
if(m==-1) m=TestSQL.IndexOf ("ORDER BY ",n+5);
//如果沒有ORDER BY 謂詞,那麼無法排序,退出;
if(m==-1)
throw new Exception ("查詢語句分析:當前沒有爲分頁查詢指定排序字段!請適當修改SQL語句。 "+strSQLInfo);
string strTableName=TestSQL.Substring (n,m-n);
//表名中有 , 號表示是多表查詢
if(strTableName.IndexOf (",")!=-1)
SqlFlag=false;
}
}
else
...{
//有子查詢;
SqlFlag=false;
}
//SQL 複雜度分析 結束
#endregion
排序語法分析#region 排序語法分析
//排序語法分析 開始
int iOrderAt=strSQLInfo.ToLower ().LastIndexOf ("order by ");
//如果沒有ORDER BY 謂詞,那麼無法排序分頁,退出;
if(iOrderAt==-1)
throw new Exception ("查詢語句分析:當前沒有爲分頁查詢指定排序字段!請適當修改SQL語句。 "+strSQLInfo);
string strOrder=strSQLInfo.Substring (iOrderAt+9);
strSQLInfo=strSQLInfo.Substring(0,iOrderAt);
string[] strArrOrder=strOrder.Split (new char []...{','});
for(int i=0;i<strArrOrder.Length ;i++)
...{
string[] strArrTemp=(strArrOrder[i].Trim ()+" ").Split (new char[]...{' '});
//壓縮多餘空格
for(int j=1;j<strArrTemp.Length ;j++)
...{
if(strArrTemp[j].Trim ()=="")
...{
continue;
}
else
...{
strArrTemp[1]=strArrTemp[j];
if(j >1 ) strArrTemp[j]="";
break;
}
}
//判斷字段的排序類型
switch(strArrTemp[1].Trim ().ToUpper ())
...{
case "DESC":
strArrTemp[1]="ASC";
break;
case "ASC":
strArrTemp[1]="DESC";
break;
default:
//未指定排序類型,默認爲降序
strArrTemp[1]="DESC";
break;
}
//消除排序字段對象限定符
if(strArrTemp[0].IndexOf (".")!=-1)
strArrTemp[0]=strArrTemp[0].Substring (strArrTemp[0].IndexOf (".")+1);
strArrOrder[i]=string.Join (" ",strArrTemp);
}
//生成反向排序語句
string strNewOrder=string.Join (",",strArrOrder).Trim ();
strOrder=strNewOrder.Replace ("ASC","ASC0").Replace ("DESC","ASC").Replace ("ASC0","DESC");
//排序語法分析結束
#endregion
構造分頁查詢#region 構造分頁查詢
string SQL=string.Empty ;
if(!SqlFlag)
...{
//複雜查詢處理
switch(strSQLType.ToUpper ())
...{
case "FIRST":
SQL="Select Top @@PageSize * FROM ( " +strSQLInfo+
" ) P_T0 @@Where ORDER BY "+strOrder;
break;
case "MID":
SQL=@"SELECT Top @@PageSize * FROM
(SELECT Top @@PageSize * FROM
(
SELECT Top @@Page_Size_Number * FROM (";
SQL+=" "+strSQLInfo+" ) P_T0 @@Where ORDER BY "+strOrder+" ";
SQL+=@") P_T1
ORDER BY "+ strNewOrder +") P_T2 "+
"ORDER BY "+strOrder;
break;
case "LAST":
SQL=@"SELECT * FROM (
Select Top @@LeftSize * FROM ("+" "+strSQLInfo+" ";
SQL+=" ) P_T0 @@Where ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "COUNT":
SQL="Select COUNT(*) FROM ( " +strSQLInfo+" ) P_Count @@Where";
break;
default:
SQL=strSQLInfo+strOrder;//還原
break;
}
}
else
...{
//簡單查詢處理
switch(strSQLType.ToUpper ())
...{
case "FIRST":
SQL=strSQLInfo.ToUpper().Replace ("SELECT ","SELECT TOP @@PageSize ");
SQL+=" @@Where ORDER BY "+strOrder;
break;
case "MID":
string strRep=@"SELECT Top @@PageSize * FROM
(SELECT Top @@PageSize * FROM
(
SELECT Top @@Page_Size_Number ";
SQL=strSQLInfo.ToUpper().Replace ("SELECT ",strRep);
SQL+=" @@Where ORDER BY "+strOrder;
SQL+=" ) P_T0 ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "LAST":
string strRep2=@"SELECT * FROM (
Select Top @@LeftSize ";
SQL=strSQLInfo.ToUpper().Replace ("SELECT ",strRep2);
SQL+=" @@Where ORDER BY "+ strNewOrder+" "+
" ) P_T1 ORDER BY "+strOrder;
break;
case "COUNT":
SQL="Select COUNT(*) FROM ( " +strSQLInfo+" @@Where) P_Count ";//edit 2008.3.29
break;
default:
SQL=strSQLInfo+strOrder;//還原
break;
}
}
//執行分頁參數替換
SQL=SQL.Replace ("@@PageSize",PageSize.ToString ())
.Replace ("@@Page_Size_Number",Convert.ToString (PageSize * PageNumber))
.Replace ("@@LeftSize",PageSize.ToString ());//
//.Replace ("@@Where",strWhere);
//針對用戶的額外條件處理:
if(strWhere!="" && strWhere.ToUpper ().Trim ().StartsWith ("WHERE "))
...{
throw new Exception ("分頁額外查詢條件不能帶Where謂詞!");
}
if(!SqlFlag)
...{
if(strWhere!="") strWhere=" Where "+strWhere;
SQL=SQL.Replace ("@@Where",strWhere);
}
else
...{
if(strWhere!="") strWhere=" And ("+strWhere+")";
SQL=SQL.Replace ("@@Where",strWhere);
}
return SQL;
#endregion
}