rjsaulakh has asked for the wisdom of the Perl Monks concerning the following question:

i have some data in the following format can i use anydata to treat this file as database and then run my sql queries on it

$D = {"Password" => "raman","_SESSION_ID" => "8ada23a94bb7950d4939c9d2 +30eabd12","image.x" => 55,"TARGET" => "","image.y" => 8,"DestPage" => + " +uest_type=authreg_CardsList&Face=fr_CA&location=cafre_pre_cards","Log +on" => "Continue...","brandname" => "","PWD" => "","_SESSION_ATIME" = +> "1117632942","_SESSION_REMOTE_ADDR" => "","USERID" => " +","MY_SITE_SIDE" => "8ada23a94bb7950d4939c9d230eabd12","UserID" => "r +aman","Face" => "fr_CA","_SESSION_EXPIRE_LIST" => {},"_SESSION_CTIME" + => "1117632942","username" => "raman","_SESSION_ETIME" => undef,"req +uest_type" => "LogLogonHandler"};

Edit by castaway - put newlines before and after example to let it wrap

Replies are listed 'Best First'.
Re: dbi::anydata
by jZed (Prior) on Jun 02, 2005 at 05:31 UTC
    The short answer is "yes you can use DBI with DBD::AnyData to treat your data as a database and run SQL queries on it".

    The somewhat longer answer is that you'll want to convert your data from the hash to a text format such as CSV (Comma Separated Values) or XML or a Fixed-length record. AnyData can work with those and others. For the example below, I'll assume you will use CSV.

    A second issue is the names of your fields. AnyData tries to stick to the rules of SQL which define fieldnames as starting with an alphabetic character and containing only alphanumerics and underscores. There are ways to circumvent that by quoting the field names, but that adds a level of complexity you don't really need. It would be much simpler to rename your fields to be valid SQL field names. I've done that in the example below (e.g. _SESSION_ID loses the underscore and image.x gets an underscore instead of a period).

    With those caveats, here's a working example that takes a hash like you've shown, inserts it into a database and then queries that database.

    #!/usr/bin/perl -w use strict; use DBI; my $dbh = DBI->connect('dbi:AnyData(RaiseError=1):'); $dbh->ad_catalog('Login','CSV','Login.csv'); my $data = {Password=>'raman',Session_ID=>'8ada23',Image_X=>55}; my @cols = qw(Password Session_ID Image_X); my @vals = @$data{@cols}; my $colStr = join ',', @cols; my $paramStr = join ',', ('?')x@cols; $dbh->do("DROP TABLE IF EXISTS Login"); $dbh->do("CREATE TABLE Login (Password TEXT,Session_ID TEXT, Image_X I +NT)"); $dbh->do("INSERT INTO Login ($colStr) VALUES ($paramStr)",{},@vals); my $sth=$dbh->prepare("SELECT Password FROM Login WHERE Image_X=?"); $sth->execute(55); $sth->dump_results; $sth->{Active}=0; # temporary workaround for DBD::File bug

    There are a couple of perl "tricks" here - I use a hash slice to extract the values from your hash and I use join to create strings of placeholders. In actual practice you probably won't create, insert, and query all in one script (or at least not in the same part of the script) but I've combined them here so you can see the full process.

    I hope this helps.

Re: dbi::anydata
by prasadbabu (Prior) on Jun 02, 2005 at 04:53 UTC

    One way is, you can convert into csv type and load the file into mysql. Then you can run the queries.

    Make use of Text::CSV module.


Re: dbi::anydata
by castaway (Parson) on Jun 02, 2005 at 06:54 UTC
    Since this seems to be a CGI::Session file from your previous posts, I would suggest that using the MySQL driver for CGI::Session would be an easier way to do this (or any of the other database drivers available on CPAN. If you havent got an actual database, I suspect getting it to store in some CSV / XML format that DBI::AnyData can use is also possible.

    PS: I still think you would be better off explaining the entire picture, and not just pieces of it.


Re: dbi::anydata
by TedPride (Priest) on Jun 02, 2005 at 06:59 UTC
    If you convert to a standard format, you can load your data into mySQL and query it from there:

    Something like the following may work for convertion:

    my (@keys, $out); @keys = sort keys %$D; print join "\t", @keys; print "\n"; $out = ''; $out .= $D->{$_} . "\t" for @keys; chop $out; print $out, "\n";
    Where the first line is the field names, so you know what order to load everything in, and \t is the delimiter. If there's a chance there may be tabs in the data, you'll want to use a different delimiter, same goes for \n for end of record.

    If (as is probably the case) you have a number of these records to go through, you'll want to cycle through them once to get a full list of all possible fields, then cycle through again to output the data in the proper order.

Re: dbi::anydata
by kprasanna_79 (Hermit) on Jun 02, 2005 at 05:04 UTC
    Hai rjsaulakh,

    You can use DBD::anydata. Check this link to get more info about. This module is very useful to retrieve data using sql queries.

    I think sql queries are very much restricted here..Please go thr the documentation for more info..