如何将Perl数组作为标量传递给子例程?

Sco*_*man 2 arrays perl scalar

这是一位新生的Perl开发者.我一直在wra my my and and and and ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...

我有以下代码(只剩下相关部分),因为其余的工作):

my @arrMissingTids;
@arrMissingTids = %hshTids;

my $missingtid;
foreach $missingtid (@arrMissingTids) {
    print "$missingtid\n";
}
Run Code Online (Sandbox Code Playgroud)

这很好用,返回我想要在数组中的值:

500000246,500000235,500000185,500000237,500000227,500000252
Run Code Online (Sandbox Code Playgroud)

但是,当我将它传递给子程序并将其包含在变量名中时,它不提供上面所写的列表,而只是提供数字1.代码如下:

myqry(@arrMissingTids);

sub myqry($) {

    my $missingtids = @_;

    $sql = "select 
        i.tid i_tid, i.name i_name
        from 
        instrument i
        where i.tid in ($missingtids)";

    print "$sql/n";
}
Run Code Online (Sandbox Code Playgroud)

打印$ sql返回以下内容:

Select i.tid i_tid, i.name i_name from instrument i where i.tid in (1)
Run Code Online (Sandbox Code Playgroud)

当我希望它返回以下内容时:

Select i.tid i_tid, i.name i_name from instrument i where i.tid in (500000246,500000235,500000185,500000237,500000227,500000252)
Run Code Online (Sandbox Code Playgroud)

提前感谢任何正确方向的指针!

dax*_*xim 7

这里有三个问题.第一个是使用函数原型,只是把它留下,看看为什么Perl 5的函数原型不好?.

第二个是函数调用中类型和函数本身的接收方不匹配.两次使用数组,或两次使用数组引用.

第三是将数据视为SQL查询的一部分,可能为SQL注入攻击打开了大门.通过将查询字符串与占位符组合在一起以便与DBI一起使用,可以安全地减轻这种情况.

myqry(@arrMissingTids);
sub myqry {
    my @missingtids = @_;
    $sql = "select
        i.tid i_tid, i.name i_name
        from
        instrument i
        where i.tid in (" . join(',', ('?') x @missingtids) . ")";
    print "$sql\n";
    # $dbh->selectall_arrayref($sql, {}, @missingtids)
}
Run Code Online (Sandbox Code Playgroud)
myqry(\@arrMissingTids);
sub myqry {
    my @missingtids = @{ shift() };
    $sql = "select
        i.tid i_tid, i.name i_name
        from
        instrument i
        where i.tid in (" . join(',', ('?') x @missingtids) . ")";
    print "$sql\n";
    # $dbh->selectall_arrayref($sql, {}, @missingtids)
}
Run Code Online (Sandbox Code Playgroud)


del*_*ver 5

如果有人还没有提到它,这里的原型是一个问题:

sub myqry($) {
Run Code Online (Sandbox Code Playgroud)

考虑一下:

sub test1($) {
    print "$_\n" foreach @_;
}

sub test2 {
    print "$_\n" foreach @_;
}

my @args = ('a', 'b', 'c');

test1(@args);
test2(@args);      
Run Code Online (Sandbox Code Playgroud)

和输出:

3
a
b
c
Run Code Online (Sandbox Code Playgroud)

到目前为止,您已经意识到标量上下文中的数组只是元素的数量,例如:

my $n = @args;
Run Code Online (Sandbox Code Playgroud)

$n通过将数组传递给子程序,将其减少为标量,最终得到一个arg,即数组中的元素数.然后你这样做:

my $missingtids = @_;
Run Code Online (Sandbox Code Playgroud)

由于($)在子定义中(数组已经缩减为一个元素),因此总是只有一个.因此,你得到1.

0.02美元:perl中的IMO原型是一个坏主意;)