1

我有一个sql语句:

uPdate emp set emp_note='I am set to this ' where emp_name='John';

我想用大写替换 oracle 特定的语句,所以我执行以下操作:

   +89      $line =~ s/ where / WHERE /ig;
   +90      $line =~ s/ set / SET /g;
   +91      $line =~ s/^select/SELECT/ig;
   +92      $line =~ s/^update/UPDATE/ig;
   +93      $line =~ s/^delete/DELETE/ig;
   +94      $line =~ s/^insert/INSERT/ig;
   +95      $line =~ s/ and / AND /g;
   +96      $line =~ s/ from / FROM /g;
   +97      $line =~ s/ in / IN /g;

以上还替换了作为值的文本(我设置为这个)。例如,上面的语句将呈现为:

UPDATE emp SET emp_note='I am SET to this ' WHERE emp_name='John';

如何避免将 perl 设置为仅替换关键字而不是 SQL 语句中的值?

问题还在于我不能使用 perl 可用的任何 SQL 包,所以我必须使用普通的旧正则表达式方式。

4

3 回答 3

1

编写一个能够理解 SQL 语法并且只替换你想要的东西的正则表达式将是非常困难的。实际上,这可能是不可能的,因为正则表达式本身无法解析像 SQL 这样的语法。您可能可以对其进行争论,使其不会替换引号内的内容,但这并不漂亮,而且无论如何它也不是一个完整的解决方案。

因此,您需要的是能够真正解析 SQL,然后根据需要使用大写关键字重新组合解析的语句。

于 2013-05-07T12:28:00.037 回答
0

Using capture groups, you can easily choose which part of the match you want to uppercase:

use strict;
my $query = "uPdate emp set emp_note='I am\' set to this ' where emp_name='John'"; 
$query =~ s/('[^'\\]*(?s:\\.[^'\\]*)*')|\b(update|where|set|select|delete|insert|and|from|in)\b/$1\U$2/gi;
print $query;

The first branch describes what you want to avoid, the second branch is the target.

于 2013-05-07T13:23:24.307 回答
-1

在 sql 语句中使用主机变量而不是文字字符串。

出于安全考虑(sql注入的危险),您无论如何都应该使用它们。

每个像样的 api 都支持它们。如果您没有,“安全”令牌几乎肯定会让您的管理员安装另一个... ;-)

于 2013-05-07T13:00:10.677 回答