我正在创建一个CGI表单来更新Sybase存储过程。
qq {execute procedure test(123,45,date,'$note');};
$note
变量是从包含故障凭单日志信息的文本框中获取的信息。因此,输入此类信息的人可以,并且很可能会使用'|"{}
等特殊字符。我很想知道是否有办法通过变量$note
将此信息传入数据库。
我的大多数研究都生成了DBI-> quote()函数,但它们似乎不起作用,我不确定它们是多么相关,因为这是一个存储过程。
现在我正在尝试以下方法:
use DBI;
$livedb = DBI->connect("dbi:Sybase:server=test","admin","pass") || die "could not connect to live DB, $DBI::errstr";
$note = "testing special characters:";
$livedb->do(qq {execute procedure jinsert(5304905,65,getdate,?);},undef,(param('$note')));
我收到以下错误:
Undefined subroutine &main::param called at test.cgi line 11.
当我使用以下方法时,如果$note
中存在'
$qy = $livedb->prepare($note);
$qy->execute($test) || die "could not journal: $DBI::errstr";
$qy->finish();
答案 0 :(得分:2)
首先,直接回答你的问题:DBI-> quote()确实是你的朋友:-)它以正确的方式为你正在使用的数据库的语言将字符串放在字符串中(这总是SELECT / UPDATE / INSERT / DELETE查询与存储过程相同,因为后者通常由前者的组合组成!)。
例如,假设已将$dbh
设置为与数据库的DBI连接,则
my $string = "Here's a string that needs \"quoting\"!";
print $dbh->quote($string);
打印如下内容:
'Here''s a string that needs "quoting"!'
请注意:
'
Here's
加倍
''
引号。它打印的确切字符串取决于您的数据库 - 有些使用略有不同的约定。
...然而
看看你在做什么,你实际上不需要做任何引用:让DBI为你做所有工作,如下:
$livedb->do(qq {execute procedure jinsert(5304905,65,getdate,?);}, undef, $note);
DBI代码知道要将?
替换为$note
时要做什么引用。
答案 1 :(得分:-3)
我终于弄明白了问题所在。我可以使用q {$note};
从perl中转义所有特殊字符。 dbh->quote
因为调用存储过程而不适用于此,问题不仅仅是匹配qoutes。单个qoutes必须传递转义存储过程。 q
和sed的组合修复了它:
use DBI;
$livedb = DBI->connect("dbi:Sybase:server=test","admin","pass") || die "could not connect to live DB, $DBI::errstr";
$note = q {testing special characters:''''''''''''''!@#$%^%^&*()};
$note =~ s/'/\\'/g;
$livedb->do(qq {execute procedure jinsert(5304905,65,getdate,?);},undef,(param('$note')))
因此简而言之,当调用诸如此类的存储过程时,单个qoutes需要被转义两次(一次是perl,另一种是存储过程)。