Perl中准备好的SQL语句

Lia*_*ell 4 perl

我是Perl的新手,我正在努力克服最初的学习曲线.

我有以下SQL语句:

        SELECT 
            node_id 
        FROM 
            pagenodes
        INNER JOIN 
            pageproducts 
        ON 
            pagenodes.node_id = pageproducts.nodeid
        INNER JOIN 
            products 
        ON 
            pageproducts.prodid = products.prodid 
        WHERE 
            products.prodid  = ?
        LIMIT 1
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,在查询中设置了LIMIT 1,我正在尝试从Perl脚本执行此查询,并将结果设置为变量.

到目前为止,我有以下内容:

my $sql =
    'SELECT 
        node_id 
    FROM 
        pagenodes
    INNER JOIN 
        pageproducts 
    ON 
        pagenodes.node_id = pageproducts.nodeid
    INNER JOIN 
        products 
    ON 
        pageproducts.prodid = products.prodid 
    WHERE 
        products.prodid  = ?
    LIMIT 1';

    my $sth = $dbh->prepare($sql);
    my $sth->execute();
Run Code Online (Sandbox Code Playgroud)

我的问题是,我如何$prod_id作为WHERE参数传入,以及如何将结果设置为变量.谢谢

sim*_*que 9

你已经很远了.你已经有了占位符(?),这很棒.您需要做的就是将参数作为参数execute传递.它将按照它们在查询中出现的顺序自动填充到占位符中.

use strict;
use warnings;
use DBI;

my $dbh = DBI->connect('dsn goes here', 'user', 'password') or die $DBI::errstr;

# stuff happens ...

my $prod_id = 1337; # or whatever

my $sql =
    'SELECT 
        node_id 
    FROM 
        pagenodes
    INNER JOIN 
        pageproducts 
    ON 
        pagenodes.node_id = pageproducts.nodeid
    INNER JOIN 
        products 
    ON 
        pageproducts.prodid = products.prodid 
    WHERE 
        products.prodid  = ?
    LIMIT 1';

my $sth = $dbh->prepare($sql);
$sth->execute($prod_id);     # no `my` here!
Run Code Online (Sandbox Code Playgroud)

LIMIT这种情况下并不重要.它也可以循环工作.

请注意,你my在前面有一个execute.这是错误的语法.my用于声明变量,但在该行中,您只调用已存在的语句句柄对象上的方法.该execute方法有一个返回值,但通常不会将其赋值给变量.如果返回值为true,则execute表示成功.如果它是假的,那就出错了.您还可以使用它or检查错误.

$sth->execute or die $dbh->errstr;
Run Code Online (Sandbox Code Playgroud)

现在,要从数据库中获取单个值,您可以在列表上下文中使用fetchrow_array.

( my $node_id ) = $sth->fetchrow_array;
Run Code Online (Sandbox Code Playgroud)

这将给你一次node_id,一次.


如果你打算只得到一个价值只有一次调用该方法,还可以节省一些代码和使用selectrow_array代替.

( my $node_id ) = $dbh->selectrow_array('SELECT node_id FROM foo WHERE prodid=? LIMIT 1', undef, $prod_id);
Run Code Online (Sandbox Code Playgroud)

同样,列表上下文很重要,因为fetchrow_arrayselectrow_array返回列表,而不是数组引用.如果没有()左侧,它将分配结果的数量(因为标量上下文).

但是,如果你想在循环中为一堆值做所有这些,它看起来有点不同.在这种情况下,请在循环外部进行准备,并在循环内部executefetchrow_array(或任何其他fetchrow_*方法)进行准备.这将使它快得多.

my $sth = $dbh->prepare($sql);
foreach my $prod_id ( @prod_ids ) {
  $sth->execute($prod_id);
  ( my $node_id ) = $sth->fetchrow_array;
  print "$node_id\n";
}
Run Code Online (Sandbox Code Playgroud)