in reply to Re^2: Error in insertion of MULTIPLE FILENAMES & CONTENTS INTO DATABASE
in thread Error in insertion of MULTIPLE FILENAMES & CONTENTS INTO DATABASE

The answer is right there in the error message -- you just have to read it carefully. Here is just the filename string from the error message:
D:/www/data/text/D:/www/data/text/Ένα μήνυμα σε όλους τους άπιστους.txt
Can you see the problem now? You have the value of $_, which comes from a file glob, and that value is:
D:/www/data/text/Ένα μήνυμα σε όλους τους άπιστους.txt
Then, inside the loop, you append that value to this string:
$ENV{'DOCUMENT_ROOT'}/data/text/
and the result of that concatenation is that the disk and directory path appears twice in the string that is passed to "open()". Fix that, and it will probably work as intended.
  • Comment on Re^3: Error in insertion of MULTIPLE FILENAMES & CONTENTS INTO DATABASE

Replies are listed 'Best First'.
Re^4: Error in insertion of MULTIPLE FILENAMES & CONTENTS INTO DATABASE
by Nik (Initiate) on Jan 01, 2008 at 23:33 UTC
    I cannot believe iam THAT careless....my apologies and think you for pointing this out.
    my $insert = $db->prepare( 'INSERT INTO articles (title, body) VALUES +(?, ?)' ); my @files = glob "$ENV{'DOCUMENT_ROOT'}/data/text/*.txt"; foreach (@files) { open FILE, "$_" or die "error opening $_: $!"; while (<FILE>) { chomp; $insert->execute(split /\t/, $_, 2) or print $db->errstr; } close FILE; }
    gives me DBD::mysql::st execute failed: called with 1 bind variables when 2 are needed.... But iam passing it 2 vars why it says iam passing it only 1?

      maybe there isn't a tab character in the string you are trying to split?

      Have you tried debugging the code yourself at all? Something simple as a sanity check would be to:

      foreach my $filename (@files) { ... while (<FILE>) { chomp; next unless length; #Skip blank lines my @params = split /\t/, $_, 2; unless (2 == @params) { warn "Line $. in $filename badly formed\n"; next; } $insert->execute() or print $db->errstr; }

      It is worth thinking about how stuff could go wrong rather than how it might go right. It is also worth checking documentation for any construct you are not absolutely sure about. Getting to know your way around the documentation for whatever you are doing is generally much better in the long run than crawling cap in hand to PerlMonks every time you hit a problem. We much prefer to solve interesting problems rather then dumb ones that are more due to laziness than inexperience.


      Perl is environmentally friendly - it saves trees
      called with 1 bind variables when 2 are needed.... But iam passing it 2 vars

      There you go making assumptions again. You are passing whatever the "split" function happens to be returning -- which would be one arg if there were no tab characters in the string being split.

        After some testing i noticed that while(<FILE>) returns a line-by-line data of the file and it is storing it in $_
        That's good by what i need is to get to whole data content in one var so the above solution aint gonna help me, of course i could concatenate every line after another to construct the whole data of the file but that would be dumb.
        I noticed after trying every weird idea that came into my mind that $data=<FILE> would save the whole file's contents in a split of a sec without the need for looping, so what i did to make the job done was the following:
        #=========== INSERTING MULTIPLE FILENAMES & CONTENTS INTO DATABASE === +========== my $data; my $insert = $db->prepare( 'INSERT INTO articles (title, body) VALUES +(?, ?)' ); my @files = glob "$ENV{'DOCUMENT_ROOT'}/data/text/*.txt"; foreach (@files) { open FILE, "$_" or die $!; $_ = map m{([^/]+)\.txt}, $_; #Strip out of the string th path +and extension leaving only the filename intact $data = <FILE>; #Grab the whole file contents at +once $insert->execute($_, $data) or print $db->errstr; close FILE; }
        All that in order to achieve opening of all files one-by-one and inserting each of the filename and its corresponding content as an entry in mysql table 'articles'

        update:

        After running this test script:

        foreach (@files) { open FILE, "$_" or die $!; print "$_", br() x3; $_ = map m{([^/]+)\.txt}, $_; #Strip out of the string the path + and extension leaving only the filename intact print "$_", br() x3; $data = <FILE>; #Grab the whole file contents at +once print "$data"; exit; close FILE; }
        i noticed 2 errors i cannot solve:

        a) The '$_' doesn't hold the value of the current filename opened without paths and extension but instead it has the number of '1' in it. Its a syntax error obviously that i have made and don't know how to properly write it.

        b) @data though it is correct because it contains the contents of each file when looping and contents are stored by me in utf8 when i write the text files
        But although i'm not striping out the filename correctly, even if i was, i will still need to re-encode the filename to utf8 before inserting into the database because filenames are greek-iso.
        i can do that as Encode::from_to($_, 'ISO-8859-7', 'utf-8') but the question is will i have to or the $insert->execute($_, $data); will do that automatic for me before inserting the values in the db?

      I cannot believe iam THAT careless....
      Why, you keep demonstrating with every post?