in reply to Finding local vs Global Error

<html> <body>

Thanks for the guys. I'm getting few errors. Here's the new code:

#!/usr/bin/perl -w use strict; use DBI; use File::Find; use Fcntl; use Getopt::Long; use Text::English; use constant TYPE_DEFAULT =>'article'; my (%opts, @files, $stop_words, $type); #User input GetOptions( \%opts, "dir=s", "stop=s", "ignore", "type=s", "numbers", "stem"); die usage() unless $opts{dir} && -d $opts{dir}; $opts{'type'} ||= TYPE_DEFAULT; #Get file names and build an array of files. find(sub{push @files, $File::Find::name}, $opts{dir}); $stop_words = load_stopwords($opts{stop}) if $opts{stop}; process_files(\@files, \%opts, $stop_words); sub load_stopwords { my $file = shift; my $words = {}; local *INFO, $_ or die "Can't open stop file: $file\n" unless -e $file; open INFO, $file or die "$!\n"; while(<INFO>) { next if /^#/; $words->{lc $1} = 1 if /(\S+)/; } close INFO; return $words; } sub process_files { #input variables: my($files, $opts, $stop_words) = @_; local( *FILE, $_ ); local $/ = "\n\n"; my $type = $opts{type}; my $dir = $opts{dir}; my %index; #Establish database variables: my($dbh, $sth1, $sth2); local(*FILE); local $/ = "\n\n"; my $file_id = 0; # initializing counter variable #Establish Database Connection $dbh = DBI->connect( "DBI:mysql:host=localhost;database=member +s", "gorillatrades", "kennyber", {PrintError=>0,RaiseE +rror=>1}); for ( my $file_id = 0; $file_id < @$files; $file_id++ ) { my $file = $files[$file_id]; my %seen_in_file; next unless -T $file; #print STDERR "Indexing $file\n"; #$index->{"!FILE_NAME:$file_id"} = $file; #Step 1: Create Library of Files: $sth1 = $dbh-> prepare("insert into library va +lues ($file, $dir, $type)"); $sth1-> execute(); open FILE, $file or die "Cannot open file: $file!\n"; while ( <FILE> ) { tr/A-Z/a-z/ if $opts{ignore}; s/<.+?>//gs; # Note this doesn't handle < or > in +comments or js while ( /([a-z\d]{2,})\b/gi ) { my $word = $1; next if $stop_words->{lc $word}; next if $word =~ /^\d+$/ && not $opts{number}; ( $word ) = Text::English::stem( $word ) if $o +pts{stem}; if ( ! $seen_in_file{$word} ) { $index{$word} .= ":" if ( exists( $in +dex{$word} )); $index{$word} .= $file_id; $seen_in_file{$word}++; } } #New Flava: Take Contents out of hash Table and into D +B foreach my $words (keys(%index)) { $sth2 = $dbh-> prepare('insert into catalog values ($words, $index{$words})'); $sth2 -> execute(); } } } } sub usage { my $usage = <<End_of_Usage; Usage: $0 -dir directory [options] The options are: -dir directory where files exist -ignore Case-insensitive index -stop Path to stopwords file -type Type of file, either email or article -numbers Include numbers in index -stem Stem words End_of_Usage return $usage; }

Now, I'm getting these errors:

perl libbuilder.pl -dir www/members/ -type= email Option type requires an argument DBD::mysql::st execute failed: You have an error in your SQL syntax ne +ar ' article)' at line 2 at libbuilder.pl line 91. Issuing rollback() for database handle being DESTROY'd without explici +t disconnect().
I know the second error requires a proper call to destroy the db hanlder. What gives /w the constant error?

Replies are listed 'Best First'.
Re^2: Finding local vs Global Error
by jZed (Prior) on Sep 21, 2005 at 00:14 UTC
    $sth2 = $dbh->prepare( 'insert into catalog values ($words, $index{$words})' );
    Perl won't interpolate $words because it's inside single quotes. If $words is a string variable, even if it were interpolated, it wouldn't be proper SQL because string values need single quotes around them (in the SQL, not in the Perl). Easiest and best fix is placeholders:
    $sth2 = $dbh->prepare('INSERT INTO catalog VALUES(?,?)'); $sth2->execute($words,$index{$words});
      That worked, but I still get this error:
      Option type requires an argument DBD::mysql::st execute failed: You have an error in your SQL syntax ne +ar ' 0)' at line 2 at libbuilder.pl line 91. Issuing rollback() for database handle being DESTROY'd without explici +t disconnect().
      BTW, Here is the structure of my table in MYSQL:
      Database changed +----------+---------------------------------+------+-----+---------+- +------+ | Field | Type | Null | Key | Default | +Extra | +----------+---------------------------------+------+-----+---------+- +------+ | filename | varchar(60) | | PRI | | + | | filedir | varchar(80) | | | | + | | filetype | enum('article','email','other') | | | article | + | +----------+---------------------------------+------+-----+---------+- +------+ 3 rows in set (0.00 sec)
      Just wondering, since I'm using enum in MYSQL, can I represent my default variable as a 0? - Cappa