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

Hi,

I am a Perl beginner. I want to query a DB and output the result row by row to text files.

eg.
sr.no. Name CodeBlock
1. mail afdsklj
afdskj
adsfasfddsaf

2. abcd l;kk;k;oiewrj
werkdsmjudjem
werjhdsujnsl
afl;af;lweorpi

3. wxyz adskflasflkafdj
kajdsflkjadslkjfa

output should be 3 text files
namely mail with content
afdsklj
afdskj
adsfasfddsaf
abcd with content
l;kk;k;oiewrj
werkdsmjudjem
werjhdsujnsl
afl;af;lweorpi
and wxyz with content
adskflasflkafdj
kajdsflkjadslkjfa
.
I am getting stuck because my code block is of variable length.
The codeblock contains several new line characters, tab and several
other commonly used separators. Hence, I am using a shell script to query
the db. The shell script outputs my query result separated by a string "(_KJ_)".


I tried using while $sqlout regmatch "(_KJ_)" create file and
and copy content to file close file. but with this I get just the first file.
I am unable to get perl read till the end of the file.

Please Help
KJ..

Replies are listed 'Best First'.
Re: export table to text.
by gone2015 (Deacon) on Oct 15, 2008 at 16:28 UTC
Re: export table to text.
by Illuminatus (Curate) on Oct 15, 2008 at 16:39 UTC
Re: export table to text.
by jethro (Monsignor) on Oct 15, 2008 at 16:53 UTC

    oshalla++ for his post. All you need to do is add some html, especially the p-tag for text and c-tag for code, to make your post somewhat readable. Hint: you can edit your message

    As a general comment, whatever you want to achieve, using a shell script between your perl script and the database is definitely the wrong idea. You will lose information in this double conversion and you have to search long for cases where a shell script can do better than native perl code.

    The advice probably everyone here will give you: Use a perl module like DBI to read your database. You find usage info and sample code within its documentation and everywhere on perlmonks, on the wider internet and in many perl books.

Re: export table to text.
by missingthepoint (Friar) on Oct 16, 2008 at 03:11 UTC

    Please, please clean up your post. It's very hard to read. Your 'sample data' makes it worse.

    This is a shot in the dark (since I can't understand you), but you might try something like this:

    #!/usr/bin/perl -w use strict; use DBI; # variables you need to fill in my $database = ''; my $table = ''; my $hostname = ''; my $port = ''; my $user = ''; my $password = ''; my $dsn = "DBI:mysql:database=$database;host=$hostname;port=$port"; my $dbh = DBI->connect($dsn, $user, $password) or die "DBI connect failed\n"; my $sth = $dbh->prepare("SELECT * FROM $table"); $sth->execute; while (my $ref = $sth->fetchrow_arrayref()) { open(my $fh, '>>', $ref->[0].'txt') or die "open: $!\n"; print $fh $ref->[1]; print $fh "\n(_KJ_)\n"; } $dbh->disconnect;

    If you're not using MySQL, you'll need to change $dsn to an appropriate data source string for the database you are using.

    That would give you mail.txt, abcd.txt, etc. Your code blocks in each text file would be separated by the string (_KJ_). Can you guarantee no code block will ever include that 6-char string?

    Disclaimer: code not tested. It could perhaps be made more efficient (namely hoisting the open()s using another SELECT) but I'll leave it as is for simplicity.


    email: perl -e 'print reverse map { chr( ord($_)-1 ) } split //, "\x0bufo/hojsfufqAofc";'
    'Under no circumstances should you program the way I say to because I say to; program the way you think expresses best what you're trying to accomplish in the program. And do so consistently and ruthlessly.' --Rob Pike

      Thanks all for helping me. ;)

      Unfortunately, I can't use DBI. Due to some constraints,
      I have to use the shell script to query the DB.

      sample output from script

      primary_only_automation_enable_KJ_create or replace procedure primary_only_a
      utomation_enable()
      begin
      -- Disable the automations that should not be running when in secondary mode
      --alter trigger group automatic_backup_system set enabled true;
      alter trigger group primary_only_triggers set e_KJ_
      profile_write_KJ_create or replace procedure profile_write(in now UTC, in s
      Char(16), in d Char(16), in j Char(16), in g Char(4), in an Char(32), in who Cha
      r(64), in val Char(32))
      begin
      write into profiler_report values( to_char(now)+' [status='+s+', journals='+j+',
      detai_KJ_
      EvalCountThresh_KJ_create or replace procedure EvalCountThresh (in Occurrenc
      eTime Integer) executable '/app/netcool/omnibus/utils/CountThreshold.pl' host 'd
      evcrb' user xxxx group xxx arguments OccurrenceTime_KJ_
      primary_only_automation_disable_KJ_create or replace procedure primary_only_
      automation_disable()
      begin
      -- Disable the automations that should not be running when in secondary mode.
      -- Requires tuning for local requirements
      alter trigger group audit_config set enabled false;
      alter trigger g_KJ_

      I want output as filenamed primary_only_automation_enable with content as

      create or replace procedure primary_only_automation_enable()
      begin
      -- Disable the automations that should not be running when in secondary mode
      --alter trigger group automatic_backup_system set enabled true;
      alter trigger group primary_only_triggers set e

      and so on

      Thanks again for help. btw Apologies for not formatting my earlier post and appreciate efforts from all to still help.

        sample output from script primary_only_automation_enable_KJ_create or...

        Perhaps you want something like this?

        #!/usr/bin/perl -w use strict; my $raw_data; open(my $in, '-|', 'sh my_shell_script.sh arg1 arg2') or die "open( +in): $!\n"; while (<$in>) { $raw_data .= $_; } my %pairs = split /_KJ_/, $raw_data; for (keys %pairs) { open(my $out, '>>', $_) or die "open(out): $!\n"; print $out %pairs{$_}; }

        Thanks for improving the formatting of your nodes. You could improve it further still by wrapping anything that's not English in code tags, like so:

        <c>$some = code($goes_here);</c>

        or:

        <c>sr.no. Name CodeBlock ...</c>

        Hint hint ;)


        email: perl -e 'print reverse map { chr( ord($_)-1 ) } split //, "\x0bufo/hojsfufqAofc";'
        'Under no circumstances should you program the way I say to because I say to; program the way you think expresses best what you're trying to accomplish in the program. And do so consistently and ruthlessly.' --Rob Pike