0

こんにちは、これから乱数を1つ選択しようとしました:

私の情報源:

use DBI;
use CGI; 

my $file = '.\input.txt';       # Name the file
open(FILE, $file) or die("Unable to open file");
my @data = <FILE>;
foreach my $line (@data)
{
  chomp $line
  my $sth = $dbh->prepare("SELECT columnA FROM table WHERE columnA LIKE '%$line%'");
  $sth->execute;
  my $result = $sth->fetchall_arrayref;


  foreach my $row ( @$result ) {
  print "- ";
  print "@$row\n";
  print "<BR />";
  }

 }

ランダムな行を1つだけ印刷するにはどうすればよいですか??? 私はそのようなことを試しました:

my $sth = $dbh->prepare("SELECT nazov_receptu FROM recepty WHERE nazov_receptu LIKE '%$line%' AND kategoria == 'p' AND (rowid = (abs(random()) % (select max(rowid)+1 from recepty)) or rowid = (select max(rowid) from recepty)) order by rowid limit 1;");

しかし、それは明らかではありません...理由はわかりません...

私は SQLite を使用しており、それを Web インターフェイスに出力しています。

input.txt がある場合に試すことができます。

A
C

データベース:

id name
1 A
2 B
3 C
4 D
5 E

アウト:

A OR C (random)
4

3 に答える 3

4

ファイル引数をループするのではなく、すぐにクエリに結合しないのはなぜですか? 次に、perl でランダム インデックスを抽出するのは簡単です。

use strict;
use warnings;                            # Always use these two pragmas

my $file   = '.\input.txt';
open my $fh, "<", $file or die "Unable to open file: $!";
chomp(my @data = <$fh>);                # chomp all lines at once
my $query  = "SELECT columnA FROM table WHERE ";
$query    .= join " OR ", ( "columnA LIKE ?" ) x @data;
                                         # add placeholder for each line
@data = map "%$_%", @data;               # add wildcards
my $sth    = $dbh->prepare($query);
$sth->execute(@data);                    # execute query with lines as argument
my $result = $sth->fetchall_arrayref;
my $randid = rand @$result;              # find random index
my $row    = $result->[ $randid ];
print "- @$row\n";
print "<BR />";

ご覧のとおり、クエリで変数を使用する適切な方法であるplaceholdersを使用しました。また、任意の量の引数を処理する簡単な方法でもあります。forクエリにはすべての行が含まれているため、ループは必要ありません。

openご覧のように、レキシカル ファイル ハンドルで 3 つの引数を使用$!する、dieステートメント内でエラー変数を使用する、適切なインデントを使用するstrict、andを使用するなど、その他のいくつかの小さな詳細も変更しましたwarnings(これらを使用せずにコーディングしないでください)。

それが私にとって最も簡単なので、私はランダム化を perl で処理しました。SQLクエリで処理する方が簡単で効果的かもしれません。あなたはORDER BY random() LIMIT 1それを最後までタックするだけで、それもうまくいくかもしれません.

于 2013-05-21T13:51:07.140 に答える
2

おそらくorder by random()

SELECT nazov_receptu FROM recepty ORDER BY RANDOM() LIMIT 1;

ランダムな行を 1 つだけフェッチする場合は、このコードをループから外してください。

my $sth = $dbh->prepare("SELECT nazov_receptu FROM recepty ORDER BY RANDOM() LIMIT 1");
$sth->execute;
my ($nazov_receptu) = $sth->fetchrow_array;
于 2013-05-21T11:52:01.503 に答える
1

クエリはforeach my $line (@data)ループ内にあるため、 の項目ごとに 1 回実行され@data、毎回異なるランダム行が取得されます。合計で 1 回だけ実行する場合は、そのループの外に移動する必要があります (「order by random() limit 1」を使用することに加えて)。

于 2013-05-21T13:15:52.450 に答える