Reputation: 13
I use the code:
$data_read=$port_obj->read($buffer);
print "$data_read\n";
The output look like this:
T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165
I want to put it in this:
$T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K
So I can write it to a MySQL database. How do I do it ?
My Database handler :
$query = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K)
VALUES ($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K)";
$query_handle = $connect->prepare($query);
$query_handle->execute();
Upvotes: 1
Views: 312
Reputation: 8376
I like it this way:
use strict;
use warnings;
my $data_read = "T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165";
my %data = split(/\s+|=/, $data_read);
my @cols = keys %data;
my $cols = join(', ', @cols);
my $placeholders = join(', ', ('?')x scalar @cols );
my $query = "INSERT INTO table ($cols) VALUES ($placeholders)";
# execute like this:
# $dbh->do($query, undef, @data{@cols});
print "$query\n";
Upvotes: 0
Reputation: 46187
Extending on comments to Jonathan Leffler's answer, perldoc keys tells us that:
The keys of a hash are returned in an apparently random order. The actual random order is subject to change in future versions of Perl, but it is guaranteed to be the same order as either the
values
oreach
function produces (given that the hash has not been modified).
(emphasis mine) This means we can use a hash to collect all the field names and their associated values without needing to explicitly enumerate them in the code:
#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
my $in = 'T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165';
my %data = $in =~ /([A-Z])=([0-9]+)/g;
my $query = 'INSERT INTO myhouse (' . join(',', keys %data)
. ') VALUES (' . join(',', values %data) . ')';
say $query;
(Note that, as TLP mentioned in a comment on the original question, this is only safe because the regex which fills %data
guarantees us that the keys will all be single uppercase letters and the values will consist solely of English-language digits. If there's any possibility that malicious input could result in uncontrolled keys or values in %data
, then you need to hardcode the field names and use placeholders for the values unless you want a visit from little Bobby Tables.)
Upvotes: 2
Reputation: 126722
You should store the data values in a hash, use placeholders in the prepared SQL statement, and pass a hash slice to the execute
method.
The code looks like this
my $data_read = 'T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165';
my %data = $data_read =~/([A-Z0-9]+)/g;
my $query_handle = $connect->prepare(<<SQL);
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?)
SQL
$query_handle->execute(@data{ qw/ T A B C D E F G H I J K / });
Upvotes: 5
Reputation: 753695
I'm not sure that putting them into the individually named variables is the best choice, but the customer is always right:
use strict;
use warnings;
my $data_read = "T=3420499518 A=914 B=97 C=49 D=436 E=428 F=863 G=34 H=771 I=214 J=493 K=165";
my $data = $data_read;
$data =~ s/[A-KT]=//g;
print "$data\n";
my($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K) = split /\s+/, $data;
my $query = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) VALUES\n" .
"($T,$A,$B,$C,$D,$E,$F,$G,$H,$I,$J,$K)";
print "$query\n";
print "\nAlternative:\n";
my(@list) = split /\s+/, $data;
print "@list\n";
my $query2 = "INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K)\nVALUES(" .
join(",", @list) . ")";
print "$query2\n";
When this snippet is run, it produces:
3420499518 914 97 49 436 428 863 34 771 214 493 165
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K) VALUES
(3420499518,914,97,49,436,428,863,34,771,214,493,165)
Alternative:
3420499518 914 97 49 436 428 863 34 771 214 493 165
INSERT INTO myhouse (T,A,B,C,D,E,F,G,H,I,J,K)
VALUES(3420499518,914,97,49,436,428,863,34,771,214,493,165)
The second half of the script shows a simpler alternative, using an array to hold the values read in.
Clearly, you can check that values were assigned to all the variables and other such error checking if you wish.
Upvotes: 1