Re: Updating lots of database fields in a single row

2013-01-22 Thread Mark Fowler
On Tuesday, January 22, 2013, Philip Skinner wrote:

my $qry = $self->dbh->prepare("UPDATE table SET " . join (sort(@fields),
> '=?, ') . " WHERE id=?");
> my $affected = $qry->execute(@hash{sort(keys %hash)}, $id);


I know this is just demoing how to use hash manipulation to get two matched
lists, but I thought it might be worth pointing out to beginners that the
above code neglects error checking.

You should always check that dbh, prepare and execute all return errors and
handle them correctly. Or, alternatively turn on exception throwing when
you make the call to dbh using RaiseError:

my $dbh = DBI->connect(
  "DBI:mysql:hostname=127.0.0.1;database=foo",
  $username,
  $password,
  { RaiseError => 1 },
);

Which is what I do in my subroutine that gets my database connection.


Updating lots of database fields in a single row

2013-01-22 Thread Mark Fowler
On Tuesday, January 22, 2013, Andrew Beverley wrote:

 is a better way of writing the following database query


With Perl there's always more than one way to do it. Greg's post rightly
recommended ORMs and pointed out that, indeed, DBIx::Class is commonly
considered the current best of breed for general use. Phil's post pointed
out how you can use Perl's syntax to easily create two lists, one for the
SQL and one for the binds.

A middle approach that isn't as heavyweight as an ORM but isn't as tedious
as rolling your own is to use a module to generate the SQL and Binds and
then pass them to DBI.

A good choice for this would be something like SQL::Abstract.

To create some SQL and binds from a hash you can just do this:

my $sa = SQL::Abstract->new;
my ($sql, @binds) = $sa->insert('table', {
  key => $value,
  key2 => $value2,
});
my $sth = $dbh->prepare($sql);
$sth->execute(@binds);

See http://goo.gl/Q8Huf for more info.

Mark
(Typed on my iOS doohicky very slowly)


Re: Updating lots of database fields in a single row

2013-01-22 Thread Greg McCarroll

In this day and age I'd be looking at an ORM[1] layer for such simple changes, 
they are almost foolproof until someone is a fool ;-). And they will probably 
avoid stupid SQL mistakes that you and I might both make.

And DBIx::Class[2] is the current best of breed, it can also 'reverse 
engineer'[3] your existing schema to Perl modules.

G.

[1] http://en.wikipedia.org/wiki/Object-relational_mapping
[2] http://search.cpan.org/~getty/DBIx-Class-0.08204/lib/DBIx/Class.pm
[3] 
http://search.cpan.org/~getty/DBIx-Class-0.08204/lib/DBIx/Class/Manual/Intro.pod#Using_DBIx::Class::Schema::Loader

On 22 Jan 2013, at 22:57, Andrew Beverley wrote:

> I've not been developing with Perl for long, so I'd like to know if
> there is a better way of writing the following database query (or is
> there a better place to ask?):
> 
> 
> my @fields = qw(field1 field2 field3 field4 field5 field6 field7 ... );
> my @updates;
> foreach my $field (@fields)
> {
>push @updates, "$field = '$hash->{$field}'" if $hash->{$field};
> }
> my $values = join ',', @updates;
> my $sth = $self->dbh->prepare("UPDATE table SET $values WHERE id = ?");
> $sth->execute($opdefs_id);
> 
> 
> Basically, I'd like to update lots of fields in a single database row.
> Obviously I could write out each updated field individually, but I
> wondered whether the above is considered tidier, or whether there is a
> better way altogether? The problem with the above code is that I'm not
> using placeholders and bind values (which I assume is to be preferred)
> so I'll also need to escape values as required.
> 
> Thanks,
> 
> Andy
> 
> 




Re: Updating lots of database fields in a single row

2013-01-22 Thread Philip Skinner

Maybe something like:

my $qry = $self->dbh->prepare("UPDATE table SET " . join (sort(@fields), 
'=?, ') . " WHERE id=?");

my $affected = $qry->execute(@hash{sort(keys %hash)}, $id);

Though I've had quite a bit to drink.

On 01/22/2013 10:57 PM, Andrew Beverley wrote:

I've not been developing with Perl for long, so I'd like to know if
there is a better way of writing the following database query (or is
there a better place to ask?):


my @fields = qw(field1 field2 field3 field4 field5 field6 field7 ... );
my @updates;
foreach my $field (@fields)
{
 push @updates, "$field = '$hash->{$field}'" if $hash->{$field};
}
my $values = join ',', @updates;
my $sth = $self->dbh->prepare("UPDATE table SET $values WHERE id = ?");
$sth->execute($opdefs_id);


Basically, I'd like to update lots of fields in a single database row.
Obviously I could write out each updated field individually, but I
wondered whether the above is considered tidier, or whether there is a
better way altogether? The problem with the above code is that I'm not
using placeholders and bind values (which I assume is to be preferred)
so I'll also need to escape values as required.

Thanks,

Andy






Updating lots of database fields in a single row

2013-01-22 Thread Andrew Beverley
I've not been developing with Perl for long, so I'd like to know if
there is a better way of writing the following database query (or is
there a better place to ask?):


my @fields = qw(field1 field2 field3 field4 field5 field6 field7 ... );
my @updates;
foreach my $field (@fields)
{
push @updates, "$field = '$hash->{$field}'" if $hash->{$field};
}
my $values = join ',', @updates;
my $sth = $self->dbh->prepare("UPDATE table SET $values WHERE id = ?");
$sth->execute($opdefs_id);


Basically, I'd like to update lots of fields in a single database row.
Obviously I could write out each updated field individually, but I
wondered whether the above is considered tidier, or whether there is a
better way altogether? The problem with the above code is that I'm not
using placeholders and bind values (which I assume is to be preferred)
so I'll also need to escape values as required.

Thanks,

Andy