As @mob says, you should use query parameters instead of fighting with how to interpolate variables directly into strings.
$store = qq(INSERT INTO main (creator_name, relationship) VALUES (?, ?));
$st = $dbi->prepare($store);
for (my $i = 0; $i < 3; $i++)
{
$st->execute($data{creatorname}, $data{"relationship$i"});
}
Advantages of using parameters:
- Easier to code, without worrying about awkward string interpolation.
- Slightly better for performance, because the SQL statement is parsed once, instead of repeatedly during each loop iteration.
- Safer with respect to application security; good defense against SQL injection.
Re your comment:
An SQL parameter can be used only in place of a single scalar value. Not an expression, or a table name or column name, or a list of values, or SQL keywords. Basically, any value you pass for the parameter value will be treated as though you had put quotes around it (there are some nuances to that, but it gives you the approximate idea).
Given the expression you described, I'd write the code like this:
$store = qq(INSERT INTO main (creator_name, relationship, complicated_column)
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL ? HOUR)));
$st = $dbi->prepare($store);
for (my $i = 0; $i < 3; $i++)
{
$st->execute($data{creatorname}, $data{"relationship$i"}, $interval);
}
Re answer from @harmic:
This is awkward to reply to another answer by adding to my own answer, but I wanted to share a code test that demonstrates the "double-interpolation" does in fact work.
$ cat test.pl
$i = 1;
$data{"key$i"} = "word";
$s = qq(string with parentheses ($data{"key$i"}));
print $s, "\n";
$ perl test.pl
string with parentheses (word)
The output of running this Perl script shows that the interpolation worked.