javascript解析SQL 语句

最近从上一个项目里面出来,开始了新的项目的工作和学习。在这承上启下之际,花了点时间反思之前学到的东西,又结合新项目知识的学习,做了一个用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[i].word.trim() == "") continue;

var script = scriptArray[i].word.trim();
if((stat = insertReg.exec(script)) != null) {
sTable = stat[0].substring(stat[0].indexOf("INTO") + 4, stat[0].indexOf("(")).trim();
var item = [scriptArray[i].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[i].rowid, sTable, "UPDATE", sCond, 100, "MEDIUM", script];
} else {
item = [scriptArray[i].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[i].rowid, sTable, "DELETE", sCond, 100, "MEDIUM", script];
} else {
item = [scriptArray[i].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;


得到的结果:
[img]http://dl.iteye.com/upload/attachment/161729/695ed9cd-843b-3811-ac7d-d4f5bcb7b998.bmp[/img]

其实很多内容都还没有考虑,比方说checklist,现在只考虑了一种,就是update/delete没有where语句。

日后慢慢改吧,如果有时间的话。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值