开发者

Can't run MySQL stored procedure from perl script

开发者 https://www.devze.com 2023-03-16 02:23 出处:网络
I am trying to access MySQL stored procedures from a perl script but I receive this error: \"can\'t return a result set in the given context\"

I am trying to access MySQL stored procedures from a perl script but I receive this error:

"can't return a result set in the given context"

As you can see, the procedure below returns two tables of results. Initially, I thought that the problem was a result of this, but the same error occurs if I call stored procs that have only one select statement.

Here is the proc:

DELIMITER $$

CREATE DEFINER=`root`@`l开发者_如何转开发ocalhost` PROCEDURE `GetPictureDataForSendMsg`(memIdVal VARCHAR(4))
begin
   select val, size3
   from members
   where memid=memIdVal;

   select id, filename, picname, picsize
   from pictures
   where memid=memIdVal order by id asc; 
end

Which is called by:

$input = 'ABC1';
$dbh = DBI->connect("DBI:mysql:$db:$server;mysql_multi_statements=true", "$user", "$password");
my $result = $dbh->prepare('CALL GetPictureDataForSendMsg($input)') or error($q, "Problem with database call");
$result->execute or error($q, "Problem with database call");

The error is linked to the execute statement. I have the necessary privileges and the newest version of MySQL; the procedure runs perfectly in the command line.

What's wrong? Thanks for your help.


You have single quotes around the CALL... statement. Variables are only interpolated in double-quoted strings, not single-quotes strings. Change those to double-quotes like this:

my $result = $dbh->prepare("CALL GetPictureDataForSendMsg($input)") or error($q, "Problem with database call");

This will interpolate the variable into the string, so you're now sending "CALL GetPictureDataForSendMsg(ABC1)" to the database. That won't work either. The database is going to put whatever you give it as a parameter directly into the SQL string. If you quote ABC1 like this 'ABC1' then it will see that as a string; otherwise it will think that ABC1 is the name of a column - which it isn't.

So, this line will work:

my $result = $dbh->prepare("CALL GetPictureDataForSendMsg('$input')") or error($q, "Problem with database call");

But there's a problem with this line too. What if the string represented by $input contains a single-quote? It will break. This is how SQL injection attacks happen. Instead you should use the DBI quote function, like this:

my $result = $dbh->prepare('CALL GetPictureDataForSendMsg('.$dbh->quote($input).')') or error($q, "Problem with database call");

I tested this on my MySQL instance (Server version: 5.1.49-1ubuntu8.1 (Ubuntu)) and it worked.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号