Listing 3. DBI implementation of program to copy user records from a source table (uregister) to a target table (uregisternew).

 use Angryman::User;
 use DBI;
 use Math::Random;
 use strict;
 use vars qw(%table $sql_field_term $insert_term %profile @ordered_fields);

 $table{in}  = 'uregister';
 $table{out} = 'uregisternew';

 # connect to database and SELECT * FROM uregister

 my $dbh = DBI->connect('DBI:mysql:test', 'root') || die "$!\n";
 my $sth = $dbh->prepare('SELECT * FROM uregister');
 my $ret = $sth->execute;

 &determine_target_database_field_order;

 # because we will re-use the target table many times, we separate the 
 # connection and insert steps with this recordset

 # iterate through the recordsets from the old table:
 while (my $record = $sth->fetchrow_hashref) {

     &randomize_user_profile;
     &fiddle_with_my_data_to_get_it_to_work_with_the_DBI_API($record);

     # INSERT 
     # the old table data into the new table along with
     # the computed hash of profile data
     my $sql = 
         "INSERT into $table{out}($sql_field_term) values($insert_term)";
     $dbh->do($sql);
 }

 # Angryman::User::Profile is a hash in which each key is a reference 
 # to an array of profile choices. For example:
 # $Angryman::User::Profile{gender} = [ 'male', 'female' ];
 # $Angryman::User::Profile{age} = ['under 14', '14-19', '20-25', ... ];
 # Because we don't have the actual data for the people in uregister,
 # we randomly assign user profile data over a normal distribution.
 # when copying it to uregisternew.
 sub randomize_user_profile {
     for (keys %Angryman::User::Profile) {
         my @tmp = @{$Angryman::User::Profile{$_}};
         $profile{$_} = random_uniform_integer(1, 0, $#tmp);
     }
     $profile{dob} = '1969-05-11';
 }

 # Hmm, I can't just give DBI my data and have it figure out the order
 # of the database fields... So here we go getting the field order 
 # dynamically so this code doesn't break with the least little
 # switch of field position.

 # In DBIx::Recordset, I would just say $handle->Names()

 sub determine_target_database_field_order {
     my $order_sth = $dbh->prepare("SELECT * FROM $table{out} LIMIT 1");
     $order_sth->execute;
     @ordered_fields = @{$order_sth->{NAME}};
     $sql_field_term = join ',',  @{$order_sth->{NAME}};
 }

 # As ubiquitous as hashes are in Perl, the DBI API does not
 # offer a way to directly commit hashes to databases.
 sub fiddle_with_my_data_to_get_it_to_work_with_the_DBI_API {
     my ($record)=@_;
     my @output_data;
     for (@ordered_fields) {
         push @output_data, $dbh->quote
           (
             defined($record->{$_}) 
             ? $record->{$_} 
             : $profile{$_}
           );
     }

     $insert_term = join ',', @output_data;
 }