# my ($dbh, $schema, $table, $cols_type) = @_;
my $dbh = $_[0];
my $schema = "$_[1]";
my $table = "$_[2]";
my $cols_type = "$_[3]";
First, stop using the parameter array like this, use your first incantation: my (...) = @_; is how you'd do it with numerous parameters.
Second, I think I saw something in a previous post that stated to stop double-quoting things ("$_[3]") unnecessarily. Take that to heart.
Is there any chance you could state an entire use case of what you're trying to achieve in a single example, along with some input data? That'd help the Monks a lot.
...or is this something you're just fooling with? (This almost seems like deja-vu for some reason).