CYQ.Data 数据层框架CYQ.Data 是一款由路过秋天创作的支持多数据库应用[Txt,Xml,Access,MSSQL,Oracle,SQLite,MySql]的底层数据库操作类库,使用本类库可以轻松快速开发项目(QQ群:6033006)。 |
CYQ.Data 文本数据库解析SQL语法
框架原理 |
|
|
| #楼主 |
昨晚突然心血来潮,想用直接执行SQL语句来操作文件数据库。 对于CYQ.Data V5版本的数据库,基本上基于MDataTable的实现,以前有解析过where条件那块语法,基本实现了简单的where条件查询和过滤。 在使用上,基本上基于MAction的封装和CodeFirst的实体方式,所以并不涉及到Select、Update、Delete语句。 为此,MProc这个执行Sql或存储过程的功能,在文本数据库里就用不了。 由于秋色园的错误日志,直接使用了文本数据库,所以,想通过sql语句批量删除点日志,所以就想到了要支持下基本的SQL语法。 要支持SQL语法支持,就得对SQL语句进行字符串解析,分拆出来各种关键字,然后结合原有增删改查机制进行处理了: 处理机制,基本如下: 1:对SQL语句,按空格分格出数组。 2:对数组进行循环,遍历并标记出所有的关键字。 3:根据关键字,分拆:Select、Update、Delete、Insert、From、Where、Set、Into及表名,还有字段名和字段值及*,count(*),Distinct等关键字。 4:根据分析出来的条件,结合原有逻辑组合处理了。 基本上就上面四个步骤了,目前除了Insert,其它的基本上完成,贴代码了: void FormatSqlText(string sqlText) { string[] items = sqlText.Split(' '); foreach (string item in items) { switch (item.ToLower()) { case "select": IsSelect = true; break; case "update": IsUpdate = true; break; case "delete": IsDelete = true; break; case "from": IsFrom = true; break; case "count(*)": IsGetCount = true; break; case "where": whereSql = sqlText.Substring(sqlText.IndexOf(item) + item.Length + 1); //该结束语句了。 return; case "top": if (IsSelect && !IsFrom) { IsTopN = true; } break; case "distinct": if (IsSelect && !IsFrom) { IsDistinct = true; } break; case "set": if (IsUpdate && !string.IsNullOrEmpty(tableName) && fieldItems.Count == 0) { int start = sqlText.IndexOf(item) + item.Length; int end = sqlText.ToLower().IndexOf("where"); string itemText = sqlText.Substring(start, end == -1 ? sqlText.Length - start : end - start); int quoteCount = 0, commaIndex = 0; for (int i = 0; i < itemText.Length; i++) { if (i == itemText.Length - 1) { string keyValue = itemText.Substring(commaIndex).Trim(); if (!fieldItems.Contains(keyValue)) { fieldItems.Add(keyValue); } } else { switch (itemText[i]) { case '\'': quoteCount++; break; case ',': if (quoteCount % 2 == 0)//双数,则允许分隔。 { string keyValue = itemText.Substring(commaIndex, i - commaIndex).Trim(); if (!fieldItems.Contains(keyValue)) { fieldItems.Add(keyValue); } commaIndex = i + 1; } break; } } } } break; default: if (IsTopN && topN == -1) { int.TryParse(item, out topN);//查询TopN } else if ((IsFrom || IsUpdate) && string.IsNullOrEmpty(tableName)) { tableName = item;//获取表名。 } else if (IsSelect && !IsFrom)//提取查询的中间条件。 { #region Select语法解析 string temp = item.Trim(','); switch (temp.ToLower()) { case "*": case "count(*)": case "top": case "distinct": break; default: if (IsTopN && topN.ToString() == temp) { break; } if (!fieldItems.Contains(temp)) { fieldItems.Add(temp.ToLower()); } break; } #endregion } break; } } } |
发表评论
论坛公告
帖子搜索
最新帖子
最新评论
- 请教博主。我mysql的提示 V5.7.7.4 MySql.xxxx:check the tablename "tbl_site_info" is exist? error:ExeDataReader():Expression #1 of ORDER BY clause is not in SELECT list, references column 'information_schema.s1.ORDINAL_POSITION' which is not in SELECT list; this is incompatible with DISTINCT 配置如下: <?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="Conn" connectionString="host=192.168.3.101;Port=3306;Database=xxxxx;uid=root;pwd=2017" providerName="MySql.Data.MySqlClient"/> </connectionStrings> </configuration>
- 查询语句有点问题,软件启动时查询语句可以从数据库查询出数据,软件一直运行时无论怎么修改数据库,查询出来的还是老数据,不知道是为什么
- 我语句中用到了union all而且两个查询都有查询条件,action.select总是不成功,不知道有没有什么好的解决办法,谢谢
- 大神,如果我想通过一个对象(从数据映射过来的)要插入的话,我需要遍历字段然后每个set一下吗?有没有更好的方法??
- 真心好用,想问下秋天直接拼写sql怕注入吗
- V4.5后,好多方法都改变了,求来个新的日志帮助
- 請問大神V5源碼要多少錢 我是和交流過的
- 楼主,,从数据库里查出来并绑定datagridview,但是显示的都是数据库里的英文名,怎么改??好纠结啊这个。。。。
- 我想问一下,主从表添加怎样处理
- 10年就过了!!!!