0

我认为我的代码存在逻辑问题。我有一个带有模板、值、行、列的 mongodb。例如 $record->{template} 它是 T1 和 $record->{column} 1 和 $record->{row} 我有一些日期(“dmY”)。我需要根据 $record->{row} 和 $record->{column} 排列 @insert_data 值

问题是我不能在那个插入语句中使用@insert_data[1] 或@insert_data[2] 或..etc,但我不明白为什么,我不明白如何解决我的问题。

while (my $record = $collection->next){
    if($record->{template} eq "T1"){
        my @insert_data;
        if($record->{column} == 1 and $record->{row} != 0){
            #my @insert_data[1] = $record->{VALUE};
        }
        if($record->{column} == 2 and $record->{row} != 0){
            #my @insert_data[2] = $record->{VALUE};
        }
        if($record->{column} == 3 and $record->{row} != 0){
            #my @insert_data[3] = $record->{VALUE};
        }
        if($record->{column} == 4 and $record->{row} != 0){
            #my @insert_data[4] = $record->{VALUE};
        }
        if($record->{column} == 5 and $record->{row} != 0){
            #my @insert_data[5] = $record->{VALUE};
        }
        if($record->{column} == 6 and $record->{row} != 0){
            #my @insert_data[6] = $record->{VALUE};
        }
        $stmt->execute(@insert_data[1],@insert_data[2],@insert_data[3],@insert_data[4],@insert_data[5],@insert_data[6],$record->{template});
    } elsif($record->{template} eq "T5"){

    } elsif($record->{template} eq "T10"){

    }   
}
}

谢谢!

4

3 回答 3

2

You're pretty much doing it wrong if you pass successive slots of an array to a method. You should never need to pass func( $a[1], $a[2], ... $a[n], ... to a sub. Passing them separately will ensure that an argument slot is used so that you might not encounter $record->{template} earlier than you expect it, but so will slice notation. ( @a[1..6] ).

And unless you're doing Perl 6 (you're not) the slots of an array are scalars, so you will need the scalar sigil ($) to assign to a slot.

As in: $insert_data[1].

Also, anywhere outside of legacy COBOL, this code is horrible: In any modern language, you should not have to branch to access structures. You should just be able to do

my $col = $record->{column}; # cache frequently referenced item.
if ( $record->{row} != 0 and $col > 0 and $col < 7 ) {
    $insert_data[ $col ] = $record->{VALUE};
}

And why you would want to pass a bunch of undefined values and only one actual value to a query is beyond me, but it looks like this:

$stmt->execute( @insert_data[1..6], $record->{template} );

Keep in mind that the slice notation ( @a[$i..$j] ) means that it will send 6 positional values as arguments. This may be important because in both your implementation and my implementation if $record->{column} is 1, the array is simply [ undef, $record->{VALUE} ]; it simply has 2 elements in it, at offset #0 and offset #1.

Without the slice notation, you pass two arguments before $record->{template}--probably unexpected. But the slice notation ensures that how ever many slots of the array have actually been assigned and allocated, the resulting expression will take up 6 positions (5 of which will be undef).

But first and foremost, for such a newbie as yourself, USUW:

use strict;
use warnings;

That needs to go at the top of your code. If you don't understand an error that strict kills the script for you can easily look it up in perlfaq and googling a solution is easy as well.

If you don't understand a message that warnings is giving, then you can also insert this library at the top of your code:

use diagnostics -verbose;

Which can tend to give you more explanation than you want to read.

于 2013-05-16T12:32:13.447 回答
1

在 之后添加检查会很棒$stmt->execute,即。

 $stmt->execute(@insert_data[1..6], $record->{template}) or die $stmt->errstr;

use strict;也可以提供帮助。

于 2013-05-16T12:32:59.513 回答
0

我注意到您没有向我们提供任何错误消息,但我认为此信息可能有用:

@array_name[integer]是一个单元素数组切片。 $array_name[integer]是数组中的一个标量值。

我建议您将值传递给execute语句而不是数组。

于 2013-05-16T12:29:17.657 回答