0

嗨,我试图从中选择一个随机数:

我的来源:

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 />";
  }

 }

我怎样才能只打印一个随机行???我尝试过这样的事情:

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带有词法文件句柄的三个参数,包括语句$!中的错误变量die,使用适当的缩进,使用strictand 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;

如果您只想获取一个随机行,请确保将此代码置于循环之外,

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)循环内,所以它将为 中的每个项目运行一次,每次都会@data获得不同的随机行。如果您希望它总共只运行一次,则需要将其移出该循环(除了使用“order by random() limit 1”)。

于 2013-05-21T13:15:52.450 回答