简体   繁体   中英

Problem with DBD and mysql in perl

Please I am having problem tracking down the problem with this code I have been trying for hours. it gives me the error DBD::mysql::st fetchrow_hashref failed: fetch() without execute() at line 15

        sub Split_Into_Words
        {
            #### Connection parameters ############################
            my $dsn =  "dbi:mysql:malware:localhost:3306";
            my $user = 'root';
            my $passwd = 'sxxxs';
            ########################################################
            my $domain ;
            my $countDir = 0 ;
            my $file = shift ;
            my $labelID  =  (split(/[.]/ , $file))[1] ; ### Split and get the middle value since format is temporay.

            #### Query String ############################################################################
             my $InsertIntoHostTable_QS  = "INSERT INTO TB_host(HostName  , UrlID , ExtID) Values (? , ? , ? ) ; ";
             my $InsertIntoDomainTable_QS = "INSERT IGNORE INTO  TB_Domain(Domain) values (?) ;" ;
             my $InsertIntoArgVal_QS = "INSERT INTO TB_Arg_Value(Arg, URL_ID)  VALUES (?  , ? ) ; " ; 
             my $InsertIntoDirectory_QS = "INSERT INTO TB_Directory(DIRNAME , DEPTH , URLID) VALUES (? , ? , ? )" ;
             my $InsertIntoExtension_QS = "INSERT IGNORE INTO TB_Extension (Extension) values ( ? ) ; ";
             my $InsertIntoExtensionNULL_QS =   "INSERT IGNORE INTO TB_Extension (ID , Extension) values (? , ? )  ; ";
             my $SelectString  = " Select URL , ID  from TB_URL where LabelID = '"  .  $labelID."';";
             my $InsertIntoFileName_QS  = "INSERT IGNORE INTO TB_FileName( filename)  VALUES (?) ; " ; 

             ###################################################################################################
             my $DBIConnect = DBI->connect($dsn , $user , $passwd) or die("Cannot connect to datadbase  $DBI::errstr\n");   


            print ("Splitting Into Words \n");


            ######Initialization of a default DB value #################
            my $sth =  $DBIConnect->prepare( $InsertIntoExtensionNULL_QS);
                    $sth->execute(1 , 'null') or die("Error Executing the Insertion" . $sth->errstr );
                    $sth->finish();
            #############################################################
            $sth =  $DBIConnect ->prepare($SelectString);
            sleep(10);
            open (FH , '<' , $file); # Open file to be read from disk

            my $i = 0;
            $sth->execute() or die("Error Executing the Insertion" . $sth->errstr );

   ->line 15        while(my $hash_ref = $sth->fetchrow_hashref )
            {
                    my $extensionID = "1";
                    my $intialURL =  $hash_ref->{URL} ;

                my $initialID = $hash_ref->{ID};
    }
    }

I'm not sure if this is the issue, but you may not need the finish after the insert. From the DBI doc :

Indicate that no more data will be fetched from this statement handle before it is either executed again or destroyed. You almost certainly do not need to call this method.

Adding calls to finish after loop that fetches all rows is a common mistake, don't do it, it can mask genuine problems like uncaught fetch errors.

If that is the problem, you may want to create a second statement handler for the select call.

Apart from the annoyingly long SQL variable names, $SelectString should contain a "?", in case $labelID contains something that could break the query or cause an injection.

prepare() doesn't absolutely require a "?", but if execute has parameters, then there must be a matching number of "?" in the query string.

First $sth->finish() is not needed because the query is an insert and doesn't return any rows.

Second 'die' should be "Error executing query", because it executing $SelectString

Note SQL convention is to write all in uppercase, and for extra safety enclose field names in backticks. Queries do not end with semicolon. Also note that "my" variables are local to that between braces, { } so that my variables in the while loop will be unavailable afterwards.

Suggest formatting thus:

sub Split_Into_Words {
    #### Connection parameters ############################
    my $dsn =  "dbi:mysql:malware:localhost:3306";
    my $user = 'root';
    my $passwd = 'sxxxs';
    ########################################################
    my $domain ;
    my $countDir = 0 ;
    my $file = shift ;
    my $labelID  =  (split(/[.]/ , $file))[1] ; ### Split and get the middle value since format is temporary.

    #### Query String ############################################################################
    my $InsertIntoHostTable_QS    = "INSERT INTO `TB_host` (`HostName`,`UrlID`,`ExtID`) VALUES (?,?,?)";
    my $InsertIntoDomainTable_QS  = "INSERT IGNORE INTO `TB_Domain` (`Domain`) VALUES (?)";
    my $InsertIntoArgVal_QS       = "INSERT INTO `TB_Arg_Value` (`Arg`,`URL_ID`) VALUES (?,?)";.
    my $InsertIntoDirectory_QS    = "INSERT INTO `TB_Directory` (`DIRNAME`,`DEPTH`,`URLID`) VALUES (?,?,?)";
    my $InsertIntoExtension_QS    = "INSERT IGNORE INTO `TB_Extension` (`Extension`) VALUES (?)";
    my $InsertIntoExtensionNULL_QS= "INSERT IGNORE INTO `TB_Extension` (`ID`,`Extension`) VALUES (?,?)";
    my $SelectString              = "SELECT `URL`,`ID` FROM `TB_URL` WHERE `LabelID`=?";
    my $InsertIntoFileName_QS     = "INSERT IGNORE INTO `TB_FileName` (`filename`) VALUES (?)";

    ###################################################################################################
    my $DBIConnect = DBI->connect($dsn , $user , $passwd) or die("Cannot connect to datadbase  $DBI::errstr\n");

    print ("Splitting Into Words \n");

    ######Initialization of a default DB value #################
    my $sth =  $DBIConnect->prepare( $InsertIntoExtensionNULL_QS);
    $sth->execute(1 , 'null') or die("Error executing the Insertion: " . $sth->errstr );
    # $sth->finish(); # not needed because it's an insert

    #############################################################
    $sth =  $DBIConnect->prepare($SelectString);
    sleep(10);
    open (FH , "<$file"); # Open file to be read from disk

    my $i = 0;
    $sth->execute($labelID) or die("Error executing query: " . $sth->errstr );

    while(my $hash_ref = $sth->fetchrow_hashref ) {
        my $extensionID = "1";
        my $intialURL = $hash_ref->{URL};
        my $initialID = $hash_ref->{ID};

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM