2

生まれたばかりの Perl 開発者です。私は頭を悩ませ、これを理解しようとしてオンラインで検索してきました... 憤慨して、私は明確さを求めてあなたに来ました.

残りが機能しているため、次のコードがあります(関連する部分のみが残っています):

my @arrMissingTids;
@arrMissingTids = %hshTids;

my $missingtid;
foreach $missingtid (@arrMissingTids) {
    print "$missingtid\n";
}

これはうまく機能し、配列に入れたい値を返します。

500000246,500000235,500000185,500000237,500000227,500000252

ただし、これをサブルーチンに渡して変数名に含めると、上記のリストではなく、番号 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";
}

$sql を印刷すると、次のように返されます。

Select i.tid i_tid, i.name i_name from instrument i where i.tid in (1)

次を返したいとき:

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

正しい方向への指針を事前にありがとう!

4

6 に答える 6

7

ここには 3 つの問題があります。1 つ目は、関数プロトタイプを使用することです。そのままにしておく必要があります。なぜ Perl 5 の関数プロトタイプが悪いのですか?を参照してください。.

2 つ目は、関数呼び出しと関数自体の受信側での型の不一致です。両方の回で配列を使用するか、両方の回で配列参照を使用してください。

3 つ目は、データを 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)
}

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)
}
于 2012-05-09T16:22:20.173 に答える
5

誰もまだ言及していない場合、ここのプロトタイプは問題です:

sub myqry($) {

このことを考慮:

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

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

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

test1(@args);
test2(@args);      

そして出力:

3
a
b
c

ここまでで、スカラー コンテキストの配列は単なる要素の数であることがわかりました。たとえば、次のようになります。

my $n = @args;

$nは 3 です。配列をスカラーに縮小するサブルーチンに渡すと、配列内の要素の数である 1 つの引数になります。次に、これを行います。

my $missingtids = @_;

これは($)、サブ定義の のため、常に 1 つになります (配列は既に 1 つの要素に縮小されています)。したがって、1を取得します。

$0.02: perl の IMO プロトタイプは悪い考えです ;)

于 2012-05-09T16:30:59.820 に答える
1

問題はここにあります:

my $missingtids = @_;

スカラー コンテキスト@_で配列を呼び出しています。これは、 の要素数に代入していることを意味します。これを回避する 1 つの方法は、配列参照を渡すことです。$missingtids@_

sub myqry {

    my $missingtids_ref = shift;
    my @missingtids=@$missingtids_ref;

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

    print "$sql/n";
}

詳細については、 および を参照しperldoc perlrefてくださいperldoc perldata

于 2012-05-09T16:23:11.863 に答える
0

すべての助けをありがとう。結局のところ、私はプロトタイプを取り除き、このコードを使用することになりました。これは完全に機能し、上記のすべてのヘルプからまとめられました。

myqry(@arrTids);

sub myqry {
   $missingtids = join(",",@_);

   .rest of code...
}
于 2012-05-11T16:00:05.527 に答える
0

したがって、文字列を作成したい

... in (1,2,3,4)

使用するjoin

myqry(join(',', @arrMissingTids))

しかし、それはむしろ裏返しです。これはより良いでしょう:

sub myqry {
    my $missingtids = join(',', @_);

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

myqry(@arrMissingTids);
于 2012-05-09T16:19:45.843 に答える
-1

テストされていませんが、おそらく正しいです:

myqry(\@arrMissingTids);

sub myqry($) {

    my $missingtids = shift; # or $_[0]

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

    print "$sql/n";
}

もちろん、参照の代わりに配列自体を渡すこともできますが、その場合、プロトタイプを変更して配列参照を書き直す必要があります。しかし、上記のものはあなたを動かすはずです。

于 2012-05-09T16:18:41.757 に答える