patternMinor
Perl DBI insert of hash
Viewed 0 times
dbiinserthashperl
Problem
How can this method that inserts a hashref into a database table be improved? It assumes that the columns of the database table are named identically to the fields in the hashref. The return value is the id field created by the insert.
It assumes that
It is used like:
Which will insert a record into the animals table:
sub insert(){
my ($table, $data) = @_;
my ($fields, $placeholders, $values) = ("", "", []);
while (my ($field, $value) = each %$data){
$fields.=", " if ($fields);
$fields.=$field;
$placeholders.=", " if ($placeholders);
$placeholders.="?";
push(@$values, $value);
}
$dbh->prepare("INSERT INTO $table ($fields) VALUES ($placeholders)")->execute(@$values);
return $dbh->last_insert_id(undef, undef, undef, undef);
}It assumes that
$dbh is a correctly initialized global database handle. It is used like:
&insert("animals", {
"type"=>"cat",
"name"=>"Patches",
"date-of-birth"=>"November 1, 2015",
"date-of-death"=>undef
});Which will insert a record into the animals table:
id | type | name | date-of-birth | date-of-death
=====================================================
1 | cat | Patches | November 1, 2015 | nullSolution
This might be a good candidate to use
This gives you a few easy features that may come in handy in the future
if you change your database, like:
SQL::Abstract in, as per DBIx::Class.sub insert {
# insert takes ( $table, \%fieldmap )
my $sql = SQL::Abstract->new();
my ( $query, @binds ) = $sql->insert( @_ );
$dbh->prepare($query)->execute(@binds);
return $dbh->last_insert_id(undef, undef, undef, undef);
}This gives you a few easy features that may come in handy in the future
if you change your database, like:
- easily change quoting character for tables/fields
- guard against injection abuse in user-specified key names, because your code currently assumes all keys will be safe. But this will not necessarily be true, and is a vulnerability target even under taint
Code Snippets
sub insert {
# insert takes ( $table, \%fieldmap )
my $sql = SQL::Abstract->new();
my ( $query, @binds ) = $sql->insert( @_ );
$dbh->prepare($query)->execute(@binds);
return $dbh->last_insert_id(undef, undef, undef, undef);
}Context
StackExchange Code Review Q#120040, answer score: 6
Revisions (0)
No revisions yet.