Chinaunix首页 | 论坛 | 博客
  • 博客访问: 195923
  • 博文数量: 21
  • 博客积分: 1410
  • 博客等级: 上尉
  • 技术积分: 657
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-05 19:07
文章分类
文章存档

2009年(6)

2008年(15)

我的朋友

分类:

2008-12-13 15:25:44

项目需要用到bdb,为了方便使用,决定用perl写一个类似sqlplus的工具访问bdb,实现insert,delete,select,update等功能。
开始是自己写代码解析sql,将一个sql语句字符串转换成复杂的数据结构,共后端访问bdb代码使用。但是自己很难写得完备,可靠。后来发现cpan上面已经有一个比较完善的sql解析模块SQL::Parser()。可以直接拿来做sql前端解析器。
用法:
use SQL::Parser;                                     # CREATE A PARSER OBJECT
my $parser = SQL::Parser->new();
#解析$sql
$parser->parse ($sql)
#解析后的结果结构
$parser->structure
此结构包含sql的信息
sql类型
    if ($parser->structure->{'command'} =~ /^SELECT$/)
    {
        exec_select ($parser);
    }
    elsif ($parser->structure->{'command'} =~ /^UPDATE$/)
    {
        exec_update ($parser);
    }
    elsif ($parser->structure->{'command'} =~ /^INSERT$/)
    {
        exec_insert ($parser);
    }
    elsif ($parser->structure->{'command'} =~ /^DELETE$/)
    {
        exec_delete ($parser);
    }
字段名
$parser->structure->{'column_names'}
where子句
$parser->structure->{'where_cols'}
表名
$parser->structure->{'table_names'}
 
但是也在使用中发现一个疑似bug,insert操作是如果一个值是负数,则SQL::Parser解析出来的值为空。
跟踪到模块内部代码,发现该模块将-50的-号解释成减号,导致无法得到正确的负值。
于是在Parser.pm模块ROW_VALUE函数中增加了以下代码:
 +2036      # by tanjie 20081213 for the number < 0
 +2037      if ($str =~ /^\-(\d+)$/) {
 +2038         if ( $type = $self->LITERAL($str) ) {
 +2039             undef $str if $type eq 'null';
 +2040             $str = '' if $str and $str eq q('');
 +2041             return { type => $type, value => $str };
 +2042         }
 +2043      }
如果某值为-号加一个数字,则将其当作一个普通值处理(不要当作表达式)
修改后该模块能正确处理负数
 
阅读(1407) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~