This is an unusual problem. It looks like you're being hit by perl's ambiguous data typing. I'd attack this one of three ways. First explicitly set your variable's type, second specify the variable type when binding it, third figure out why your database is so lame-brained.
Here's what the first two look like. If I wanted to ensure your catalog_id value was a number I'd write it as 0 + $self -> param('catalog_id'). If I wanted to affect DBI's binding then you use the bind_param function something like this. Refer to your DBI documentation in the "Data Types for Placeholders" section.
# Alter the data type of the value as it's being passed
$sth -> execute(
0 + $self -> param('catalog_id'),
# Specify the data type explicitly
$sth -> bind_param( 1, $self->param('catalog_id'), SQL_INTEGER);
$sth -> bind_param( 2, $start_item );
$sth -> bind_param( 3, 20 );
$sth -> execute;
Out of curiousity, which database are you using?
Seeking Green geeks in Minnesota