perl中DBD和mysql的问题

时间:2011-08-17 21:25:38

标签: mysql perl dbd

请问我使用此代码追踪问题时遇到问题我已经尝试了几个小时。它给了我错误DBD :: mysql :: st fetchrow_hashref failed:fetch()没有第15行的execute()

        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};
    }
    }

2 个答案:

答案 0 :(得分:2)

我不确定这是否是问题,但插入后你可能不需要完成。来自DBI doc

  

表示不再从此语句句柄中获取更多数据   在再次执行或销毁之前。你几乎肯定   不需要调用此方法。

     

添加对完成后循环的调用以获取所有行是很常见的   错误,不要这样做,它可以掩盖像未捕获的真正的问题   错误。

如果这是问题,您可能想为select调用创建第二个语句处理程序。

答案 1 :(得分:1)

除了恼人的长SQL变量名外,$ SelectString应包含“?”,以防$ labelID包含可能破坏查询或导致注入的内容。

prepare()并不一定要求“?”,但如果execute有参数,那么必须有匹配的数字“?”在查询字符串中。

不需要第一个$ sth-&gt; finish()因为查询是插入而不返回任何行。

第二个'die'应该是“执行查询时出错”,因为它执行$ SelectString

注意SQL约定是以大写形式全写,为了额外的安全性,在反引号中包含字段名称。查询不以分号结尾。另请注意,“my”变量是大括号{}之间的变量,因此我的变量在while循环中将不可用。

建议格式化:

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};

    }