项目需要用到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 }
如果某值为-号加一个数字,则将其当作一个普通值处理(不要当作表达式)
修改后该模块能正确处理负数
阅读(1492) | 评论(0) | 转发(0) |