sql查詢語句如何解析成分頁查詢?


我們公司主要mysql存儲數據,因此也封裝了比較好用mysql通用方法,然后,我們做大量接口,在處理分頁查詢接口,沒有很好分查詢方法。sql查詢 語句如何解析成“分頁查詢”和“總統計”兩條語句。可能,很多人在處理“總統計”是這樣:“select count(*) from (<sql原查詢語句>) ”,而不是把原sql查詢語句中columns替換成“count(*)”;相比前者統計查詢效率高不高,大家心知肚明。“分頁查詢”很簡單,對於mysql語句就是在原sql查詢語句后面加上“limit 數字 offset 數字”

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace MySqlTest
{
    class Program
    {
        static void Main(string[] args)
        {
            string sql = "select id,code,name,modifytime,storeid from retail_cashier where profileid=@profileid and  storeId=@storeId order by id";
            var parts = MysqlPageHelper.BuildPageQuery(sql, 1, 20);

            Console.WriteLine("sql:{0};",parts.Sql);
            Console.WriteLine("SqlCount:{0}", parts.SqlCount);
            Console.WriteLine("SqlPage:{0}",parts.SqlPage);
            Console.WriteLine("SqlOrderBy:{0}", parts.SqlOrderBy);
            Console.ReadKey();
        }
    }


    public class MysqlPageHelper
    {
        public Regex RegexColumns = new Regex(@"\A\s*SELECT\s+((?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|.)*?)(?<!,\s+)\bFROM\b",
            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        public Regex RegexDistinct = new Regex(@"\ADISTINCT\s",
            RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        public Regex RegexOrderBy =
            new Regex(
                @"\bORDER\s+BY\s+(?!.*?(?:\)|\s+)AS\s)(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?(?:\s*,\s*(?:\((?>\((?<depth>)|\)(?<-depth>)|.?)*(?(depth)(?!))\)|[\[\]`""\w\(\)\.])+(?:\s+(?:ASC|DESC))?)*",
                RegexOptions.RightToLeft | RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline | RegexOptions.Compiled);

        private string _sqlSelectRemoved = null;
        public void SplitSql(string sql, long skip, long take)
        {
            this.Sql = sql;
            this.SqlCount = null;
            this.SqlOrderBy = null;

            // 從中提取列
            var m = RegexColumns.Match(this.Sql);
            if (!m.Success)
                throw new Exception("無法解析分頁查詢的SQL語句");

            // sql語句中columns替換成count(*)
            var g = m.Groups[1];
            this._sqlSelectRemoved = this.Sql.Substring(g.Index);

            if (RegexDistinct.IsMatch(this._sqlSelectRemoved))
                this.SqlCount = this.Sql.Substring(0, g.Index) + "COUNT(" + m.Groups[1].ToString().Trim() + ") " + sql.Substring(g.Index + g.Length);
            else
                this.SqlCount = this.Sql.Substring(0, g.Index) + "COUNT(*) " + sql.Substring(g.Index + g.Length);

            // sql語句最后order by
            m = RegexOrderBy.Match(this.SqlCount);
            if (m.Success)
            {
                g = m.Groups[0];
                this.SqlOrderBy = g.ToString();
                this.SqlCount = this.SqlCount.Substring(0, g.Index) + this.SqlCount.Substring(g.Index + g.Length);
            }
            //分頁讀取數據
            SqlPage = string.Format("{0}\nLIMIT {1} OFFSET {2}", this.Sql, take, skip);
        }


        public static MysqlPageHelper BuildPageQuery(string sql, long skip, long take)
        {
            var page=new MysqlPageHelper();
            page.SplitSql(sql,skip,take);
            return page;
        }

        public string Sql { get; private set; }
        public string SqlPage { get;private set; }
        public string SqlCount { get;private set; }
        public string SqlOrderBy { get;private set; }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM