zoukankan      html  css  js  c++  java
  • 发一段非万能的sql分页代码

    百度一下,发现N多万能的sql分页办法, 不过大都有一个共性,就是把一段sql的各个部分折成几个参数,然后拼接sql

    而且很多都只支持单表.

    我发的代码就是为了解决上面这两个问题的.

    使用注意事项:

    1.传入的sql必须是可以正常执行的sql

    2.传入的sql必须有排序(order by )

    3.如果使用的是SqlServerDialect,最好传入正确totalCount,否则最后一页的数据可能跟你想像中的不太一样,

    如果是SqlServer2005Dialect的话,不存在此问题

    4.基本上可以满足绝大部分的sql语句,大家可以试试复杂的sql,有兴趣的话,可以跟我联系,大家一起完善

    下面这段是针对sql server 2000的,不过2005与2008一样可以用

    publicclass SqlServerDialect:ISqlDialect
    {
    #region ISqlDialect 成员

    publicstring GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount)
    {
    if (string.IsNullOrEmpty(sql))
    return sql;


    string orderByText = GetOrderByText(sql);
    if (string.IsNullOrEmpty(orderByText))
    thrownew ArgumentException("缺少order by ");

    if (pageNum ==1)
    return GetFirstPageSqlText(sql, pageSize);

    int rowCount = pageSize;
    if (totalCount >0)
    {
    if (totalCount < pageNum * pageSize)
    {
    rowCount
    = totalCount - (pageNum -1) * pageSize;
    }
    if (rowCount <0)
    rowCount
    =0;
    }

    int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    thrownew ArgumentException("缺少select关键字", sql);

    //string orderByText = GetOrderByText(sql);
    string reverseOrderByText = GetReverseOrderByText(orderByText);
    StringBuilder sb
    =new StringBuilder();
    sb.AppendFormat(
    "select * from ( select top {0} * from ( select top {1}", rowCount, pageSize * pageNum);
    sb.Append(sql.Substring(pos
    +"select".Length));

    sb.Append(
    ") as temptable1 order by ");
    sb.Append(reverseOrderByText);
    sb.Append(
    ") as temptable2 order by ");
    sb.Append(orderByText);
    return sb.ToString();

    }

    #endregion

    privatestaticstring GetFirstPageSqlText(string sql, int pageSize)
    {
    int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    thrownew ArgumentException("缺少select关键字", sql);

    StringBuilder sb
    =new StringBuilder(sql.Length +20);
    sb.Append(sql);
    sb.Insert(pos
    +"select".Length +1, String.Format("top {0} ", pageSize));
    return sb.ToString();
    }

    privatestaticstring GetOrderByText(string sql)
    {
    int len ="order by".Length;
    int pos = sql.LastIndexOf("order by", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    {
    returnstring.Empty; ;
    }
    return RemoveAlias(sql.Substring(pos + len));
    }

    privatestaticstring GetReverseOrderByText(string orderByText)
    {
    StringBuilder sb
    =new StringBuilder();
    string[] cols = orderByText.Split(',');

    for (int i =0; i < cols.Length; i++)
    {
    if (i >0)
    sb.Append(
    ",");
    int pos = cols[i].LastIndexOf(" desc", StringComparison.OrdinalIgnoreCase);
    if (pos >-1)
    {
    sb.Append(cols[i].Substring(
    0, pos)).Append(" asc");
    }
    else
    {
    pos
    = cols[i].LastIndexOf(" asc", StringComparison.OrdinalIgnoreCase);
    if (pos >-1)
    {
    sb.Append(cols[i].Substring(
    0, pos)).Append(" desc");
    }
    else
    {
    sb.Append(cols[i]).Append(
    " desc");
    }
    }
    }
    return sb.ToString();

    }

    privatestaticstring RemoveAlias(string orderByText)
    {
    StringBuilder sb
    =new StringBuilder();

    string[] cols = orderByText.Split(',');

    for (int i =0; i < cols.Length; i++)
    {
    if (i >0)
    sb.Append(
    ",");

    int pos = cols[i].IndexOf(".");

    if (pos >-1)
    {
    sb.Append(cols[i].Substring(pos
    +1));
    }
    else
    {
    sb.Append(cols[i]);
    }
    }
    return sb.ToString();

    }

    }

    接着来个sqlserver2005的

    publicclass SqlServer2005Dialect : ISqlDialect
    {
    #region ISqlDialect 成员

    publicstring GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount)
    {
    if (string.IsNullOrEmpty(sql))
    return sql;

    string orderByText = GetOrderByText(sql);
    if (string.IsNullOrEmpty(orderByText))
    thrownew SqlNullValueException("缺少order by ");


    if (pageNum ==1)
    return GetFirstPageSqlText(sql, orderByText, pageSize);

    int startIndex = (pageNum -1) * pageSize;
    int endIndex = startIndex + pageSize;

    int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    thrownew ArgumentException("缺少select关键字", sql);

    StringBuilder sb
    =new StringBuilder();
    sb.Append(sql);
    sb.Insert(pos
    +"select".Length +1, String.Format(" top 100 percent row_number() OVER(order by {0}) AS _rowNum, ", orderByText));
    sb.AppendFormat(
    " ) select * from _pageSql where _rowNum between {0} and {1} ", startIndex +1, endIndex);
    sb.Insert(
    0, "with _pageSql as ( ");

    return sb.ToString();
    }

    #endregion

    privatestaticstring GetFirstPageSqlText(string sql, string orderBySql, int pageSize)
    {
    int pos = sql.IndexOf("select", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    thrownew ArgumentException("缺少select关键字", sql);

    StringBuilder sb
    =new StringBuilder(sql.Length +20);
    sb.Append(sql);
    sb.Insert(pos
    +"select".Length +1, String.Format("top {0} ", pageSize));
    //sb.Append(" " + orderBySql);
    return sb.ToString();
    }

    privatestaticstring GetOrderByText(string sql)
    {
    int len ="order by".Length;
    int pos = sql.LastIndexOf("order by", StringComparison.OrdinalIgnoreCase);
    if (pos <0)
    {
    returnstring.Empty; ;
    }
    return sql.Substring(pos + len);
    }

    }

    像oracle/sqlite/mysql的,就很简单,不发了.

    顺便把接口也发一下

    publicinterface ISqlDialect
    {
    string GetPageSqlText(string sql, int pageSize, int pageNum, int totalCount);

    }
  • 相关阅读:
    python常用包收集
    python pep 8
    常用python字符串处理
    安全资源整理
    WordPress下载安装简单配置实例
    PHP框架学习之Laravel基本功能
    PHP框架学习之Laravel安装
    PHP面试题之优化
    PHP面试题之小杂鱼
    PHP面试题之文件目录操作
  • 原文地址:https://www.cnblogs.com/builderman/p/2110108.html
Copyright © 2011-2022 走看看