【问题标题】:Problem with DBD and mysql in perlperl中DBD和mysql的问题
【发布时间】:2011-10-29 07:20:22
【问题描述】:

请我在追踪这段代码的问题时遇到了问题,我已经尝试了几个小时。它给了我错误 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};
    }
    }

【问题讨论】:

  • 首先,在所有prepare() 调用之后添加一个... or die $dbh-&gt;errstr;。其次,在$SelectString 的SQL 中,将$labelID 设为绑定参数,而不是像那样连接。我怀疑解决这两个问题要么解决问题,要么让真正的问题更明显。

标签: mysql perl dbd


【解决方案1】:

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

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

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

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

【讨论】:

  • 傻我。有效 !!我只需要创建另一个语句处理程序。谢谢
【解决方案2】:

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

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

不需要第一个 $sth->finish(),因为查询是一个插入并且不返回任何行。

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

注意 SQL 约定是全部用大写字母书写,并且为了额外的安全,将字段名称括在反引号中。查询不以分号结尾。另请注意,“我的”变量在大括号 { } 之间是局部变量,因此我在 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};

    }

【讨论】:

    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    • 2013-02-23
    • 1970-01-01
    • 2014-06-27
    相关资源
    最近更新 更多