Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Dear Monks,
I've got a hash containing some data like:
%addrRow=('name'=>'Billy','email'=>'billy@email.com','city'=>'NY','country'=>'US');
What I want to do is to have this entire stuff to be stored in a scalar.
And then store the values of this scalar into MS Access via ODBC.
The one way I can think of doing this is writing the scalar into a flat file and then reading it back from the flat file.
Is there a better and more efficient way to do the same?
Thanks in advance
-oyster
Re: print hash into scalar
by grinder (Bishop) on Dec 23, 2002 at 07:59 UTC
|
You could use Storable as a mechanism for serialising your hash into a scalar. I would recommend this approach as it's quite space-efficient. Much more so than, for example, Data::Dumper with $Data::Dumper::Indent = 0.
On the other hand, if Storable is space-efficient, it is because the data structure is written in a binary format. That means that you can't easily inspect the values during a debugging run, whereas you could with Data::Dumper.
Finally, Data::Dumper is dangerous for serialisation, because you recover it with an eval, which gives the bad guys a chance to Nasty Things™ to your system.
print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
| [reply] [d/l] |
|
I would strongly concur with the comments of grinder above. I would however add that care should also be taken with Storable with regard to the storage mechanism employed by this module for cross-platform compatibility.
If the deserialisation of stored information is being performed across multiple platforms, it is important to employ the nstore routine for serialisation as this stores information in network order. Furthermore, double values are stored stringified to ensure portability, at the slight risk of losing some precision in the lowest order decimals.
Another feature of Storable which may also be of use in caching and information retrieval is the canonical representation of stored hashes. Normally, the elements of hashes are stored in the same order as they are stored internally by Perl (eg. pseudo-randomly). This allows serialised data to be compared in their frozen form which can be useful for caching serialised information.
perl -le 'print+unpack("N",pack("B32","00000000000000000000001000000101"))'
| [reply] [d/l] |
Re: print hash into scalar
by mt2k (Hermit) on Dec 23, 2002 at 08:28 UTC
|
#!perl -w
use strict;
use Data::Dumper;
my %addrRow = (
'name' => 'Billy',
'email' => 'billy@email.com',
'city' => 'NY',
'country' => 'USA'
);
$Data::Dumper::Indent = 0;
$Data::Dumper::Purity = 1;
my $scalar = Data::Dumper->Dump(
[\%addrRow], ['*addrRow']
);
$scalar now contains the hash. You can print() the value to see the hash, print the value to a file and later do() the file to recreate the hash, or use an eval() on the scalar... You can do quite a bit :) Sadly, I used to use this as a database, until I found out that the pages load quite slowly when multiple requests are waiting for the release of a sequentially locked file while Data::Dumper does its job. Now I use MySQL for nearly everything.
Update: Just to add something so I don't get yelled at :) If you do indeed use Data::Dumper to save the hash to a file and then use do() to recreate the hash, you should most likely lock a sequential file to prevent damage to the data. Also, if you 'use strict' (which you should be), you will have to declare the hash via our() or use vars() before do()ing the file. Otherwise, strict will complain, etc etc.
-------------------------------------
eval reverse@{[lreP
=>q{ tsuJ\{qq},' rehtonA'
,q{\}rekcaH },' tnirp']}[1+1+
1,1-1,1+1,1*1,(1+1)*(1+1)];
-------------------------------------
| [reply] [d/l] |
Re: print hash into scalar
by Ryszard (Priest) on Dec 23, 2002 at 07:46 UTC
|
When you say you want this stored as a scalar, and assuming you've got multiple records, how do you want to preserve the relationship in the data? There are various method to do this however what you've got here looks pretty good IMO.
Having never worked with MS Access and the DBI, I cant comment on how (or if) it actually works, however if it works the same as a "regular" ole DBI supported database, i'd be using a simple sql and placeholders to insert this data into your database.
There are many nodes here you can lookup examples for... | [reply] |
Re: print hash into scalar
by davorg (Chancellor) on Dec 23, 2002 at 08:00 UTC
|
You probably want to look at Data::Dumper or Storable.
--
<http://www.dave.org.uk>
"The first rule of Perl club is you do not talk about
Perl club." -- Chip Salzenberg
| [reply] |
Re: print hash into scalar
by poj (Abbot) on Dec 23, 2002 at 10:24 UTC
|
If you want data from the hash to go straight into Access, you could try something like this ;
use strict;
use warnings;
use Win32::ODBC;
# see Programming the Perl DBI page 167
# connect to data source
my $db = new Win32::ODBC("DSN=mydsn;")
or die Win32::ODBC::Error();
# some data to insert
my %addrRow = ( 'name' => 'Billy', 'email' => 'billy@email.com', 'city
+' => 'NY', 'country' => 'USA' );
my $name = $addrRow{'name'};
my $email = $addrRow{'email'};
my $city = $addrRow{'city'};
my $country = $addrRow{'country'};
# prepare and execute
if ( $db->Sql( "INSERT INTO address (name,email,city,country)
VALUES (\'$name\',\'$email\',\'$city\',\'$country\') " ) ){
print "SQL Error; ". $db->Error()."\n";
}
# exit
$db->Close();
poj
| [reply] [d/l] |
|
| [reply] |
|
Normally I would, but does Win32::ODBC support placeholders ? The DBI book I have said it didn't but things may have changed.
poj
| [reply] |
|
|
|