设为首页 收藏本站
查看: 924|回复: 0

[经验分享] javascript解析SQL 语句

[复制链接]

尚未签到

发表于 2016-11-11 04:54:19 | 显示全部楼层 |阅读模式
最近从上一个项目里面出来,开始了新的项目的工作和学习。在这承上启下之际,花了点时间反思之前学到的东西,又结合新项目知识的学习,做了一个用javascript解析SQL语句的小程序。
在上一个项目的重要工作就是写SQL语句,insert,delete和update语句为主,通过配置数据库中的记录, 来展现用户可定制的页面显示。其中很大一部分工作花费在对SQL语句的检查中。 根据数据库表结构的逻辑关系,我们必须保证输入的数据是有效的,并且是有意义的。为此,我们专门有一个checklist的文档来描述。
当时就很想做一个自动化的工具,每次写完脚本以后,往工具里面一传,马上就能出来个report,说明哪哪不对了,哪个checklist没过了,一目了然。
但是总是太懒惰了,给自己找各种各样的借口,最终也没有去做。
现在的新项目用的是Dojo开发的RIA应用,第一次接触客户端层的开发,相对于传统的J2EE服务器端的开发,根本就是一头雾水。 经历了整整两周时间的混乱,终于多少对javascript的客户端开发有了一定的了解。
于是就想到了为前一个项目做点贡献,利用dojo/javascript开发一个解析SQL语句的web小工具。
技术难点:
1. 利用正则表达式匹配SQL语句。
2. 能够解析出scripts中的注释及COMMITS语句并提取出。
代码:
1. validateSQL函数中定义了匹配SQL语句的正则表达式,并对每一种SQL分别处理,并返回结果。
2. splitSqlArray通过分号来区分语句,同时去掉所有注释。 要注意的是,SQL的value中有可能包含分号, 需要把这种情况考虑到。

validateSQL: function(content) {
var insertReg = /INSERT[\s+\n+]+INTO[\s+\n+]+\S+[\s*\n*]*\([\S*\s*\n*]+\)[\s*\n*]+VALUES[\s*\n*]*\([\S*\s*\n*]+\)/;
var updateReg = /UPDATE[\s+\n+]+\S+[\s+\n+]+SET[\S*\s*\n*]+(WHERE[\S*\s*\n*]+)?/;
var deleteReg = /DELETE[\s+\n+]+FROM[\s+\n+]+\S+[\s+\n+]+(WHERE[\S*\s*\n*]+)?/;
var commitReg = /COMMIT;/;
var scriptArray = Util.splitSqlArray(content);
var result = new Array();
for(var i = 0; i <scriptArray.length; i++) {
if(scriptArray.word.trim() == "") continue;
var script = scriptArray.word.trim();
if((stat = insertReg.exec(script)) != null) {
sTable = stat[0].substring(stat[0].indexOf("INTO") + 4,  stat[0].indexOf("(")).trim();
var item = [scriptArray.rowid, sTable, "INSERT", "NA", 1, "LOW", script];
} else if((stat = updateReg.exec(script))!= null) {
sTable = stat[0].substring(stat[0].indexOf("UPDATE") + 6,  stat[0].indexOf("SET")).trim();
if(stat[0].indexOf("WHERE") > 0) {
sCond = stat[0].substring(stat[0].indexOf("WHERE") + 5).trim();
item = [scriptArray.rowid, sTable, "UPDATE", sCond, 100, "MEDIUM", script];
} else {
item = [scriptArray.rowid, sTable, "UPDATE", "NA", 100, "HIGH", "You don't have a where clause!"];
}
} else if((stat = deleteReg.exec(script))!= null) {
sTable = stat[0].substring(stat[0].indexOf("FROM") + 4,  stat[0].indexOf("WHERE")).trim();
if(stat[0].indexOf("WHERE") > 0) {
sCond = stat[0].substring(stat[0].indexOf("WHERE") + 5).trim();
item = [scriptArray.rowid, sTable, "DELETE", sCond, 100, "MEDIUM", script];
} else {
item = [scriptArray.rowid, sTable, "UPDATE", "NA", 100, "HIGH", "You don't have a where clause!"];
}
} else {
item = null;
}
if(item != null) result[result.length] = item;
}
return result;
}

splitSqlArray:function(content) {
var count = 1;
var started = false;
var result = new Array();
for(var i = 0; i < content.length; i++) {
var cChar = content.charAt(i);
if(cChar == '-') {
if(content.charAt(i + 1) == '-') {
while(true) {
cChar = content[++i];
if(cChar == '\n') {
count++;
break;
}
}
continue;
}
}
if(cChar == '\n'){
count++;
continue;
}
if(!started) {
var iRowid = count;
var sWord = new Array();
sWord[sWord.length] = cChar;
started = true;
} else if(cChar == "'"){
sWord[sWord.length] = cChar;
while(true) {
cChar = content[++i];
sWord[sWord.length] = cChar;
if(cChar == "'") break;
}
} else if(cChar == ";") {
result[result.length] = {rowid : iRowid, word:(sWord.join(""))};
started = false;
} else {
sWord[sWord.length] = cChar;
}
}
return result;
}

测试用的SQL:

--  #########  INSERTs  for  CLSFDWAPS  on server S  #########  --
--  ###  PROV.APPROVED_FIELDS_MAPPING
INSERT INTO PROV.APPROVED_FIELDS_MAPPING (APP_CODE, GROUP_NO, INPUT_FORM_FIELD, INPUT_FORM_VAL, "TYPE")
VALUES ('CLSFDWAPS', 01, 'Region', 'Region_AseanIsa', 'INTRANET');
INSERT INTO PROV.APPROVED_FIELDS_MAPPING (APP_CODE, GROUP_NO, INPUT_FORM_FIELD, INPUT_FORM_VAL, "TYPE")
VALUES ('CLSFDWAPS', 02, 'Region', 'Region_AusNz', 'INTRANET');
INSERT INTO PROV.APPROVED_FIELDS_MAPPING (APP_CODE, GROUP_NO, INPUT_FORM_FIELD, INPUT_FORM_VAL, "TYPE")
VALUES ('CLSFDWAPS', 03, 'Region', 'Region_Gcg', 'INTRANET');
-- here is what I am testing.
-- again still test.
UPDATE PROV.APPROVED_FIELDS_MAPPING SET APP_CODE='CLSFDWAPS';
commit;

得到的结果:
DSC0000.bmp
其实很多内容都还没有考虑,比方说checklist,现在只考虑了一种,就是update/delete没有where语句。
日后慢慢改吧,如果有时间的话。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-298511-1-1.html 上篇帖子: T-SQL 触发器 下篇帖子: DSL-SQL源码分析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表