If you stop at
my @question_marks = ('?') x @column_names; #Thx [Zaxo]
you're going to generate unhappy queries. Try something like
my $question_marks = join(',', ('?') x @column_names);
You could try to remember do local $" = ','; before interpolating @question_marks, but that seems to me to be an uneccessary, error-prone step.