special Characters in Perl

2019-09-20 13:47发布

I'm creating a CGI form to update a Sybase stored procedure.

qq {execute procedure test(123,45,date,'$note');}; the $note variable is information obtained from a textbox that contains trouble ticket log information. As such people who enter such information can, and most likely will use special characters such as '|"{} etc. Im curious to know if there is a way to get this information into the database via the variable $note.

Most of my research has produced DBI->quote() functions, but they dont seem to work, and Im not sure how relevant those are since this is a stored procedure.

Right now I am trying the following:

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')));

I get the following error:

Undefined subroutine &main::param called at test.cgi line 11.

when I use the below methods, the code fails if a ' exists in $note:

$qy = $livedb->prepare($note);
$qy->execute($test) || die "could not journal: $DBI::errstr";
$qy->finish();

2条回答
聊天终结者
2楼-- · 2019-09-20 14:21

I finally figured out what the problem was. I am able to escape all of the special characters from perl using q {$note};. dbh->quote is not applicable here since its calling a stored procedure, and the issue isn't simply matching qoutes. Single qoutes have to be passed escaped to the stored procedure. A combination of q and sed fixed it:

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')))

So in a nutshell, when calling a stored procedure such as this one, single qoutes need to be escaped twice (once in perl, a second type for the stored procedure).

查看更多
太酷不给撩
3楼-- · 2019-09-20 14:41

Firstly, to answer your question directly: DBI->quote() is indeed your friend here :-) It puts quotes round the string in the correct way for the language of the database you're using (which is invariably the same for SELECT/UPDATE/INSERT/DELETE queries as for stored procedures, since the latter usually consist of combinations of the former!).

For example, assuming $dbh has been set up as your DBI connection to your database, then

my $string = "Here's a string that needs \"quoting\"!";

print $dbh->quote($string);

prints something like:

'Here''s a string that needs "quoting"!'

Notice how:

  • It's doubled the ' in Here's
  • It's put '' quotes around the whole string.

The exact string that it prints will depend on your database - some use slightly different conventions.

However...

Looking at what you're doing, you shouldn't actually need to do any quoting: let DBI do all the work for you, like this:

$livedb->do(qq {execute procedure jinsert(5304905,65,getdate,?);}, undef, $note);

The DBI code knows what quoting to do in order to replace the ? with $note.

查看更多
登录 后发表回答