# 使用 Perl 绑定 SQLite 参数&列

> 原文： [http://zetcode.com/db/sqliteperltutorial/bind/](http://zetcode.com/db/sqliteperltutorial/bind/)

SQL 语句通常是动态构建的。 用户提供一些输入，并将其内置到语句中。 程序员每次处理用户的输入时都必须谨慎。 它具有一些严重的安全隐患。 动态构建 SQL 语句的推荐方法是使用参数绑定。

绑定参数可以防止 SQL 注入程序。 它会自动转义一些特殊字符并允许正确处理它们。 当我们准备语句并绑定参数时，许多数据库也会显着提高其性能。

```perl
#!/usr/bin/perl

use strict;
use DBI;

my $dbh = DBI->connect(          
    "dbi:SQLite:dbname=test.db", 
    "",                          
    "",                          
    { RaiseError => 1 },         
) or die $DBI::errstr;

my $name = "Volkswagen"; 

my $sth = $dbh->prepare("SELECT * FROM Cars WHERE Name = ?");
$sth->execute($name);

my ($id, $name, $price) = $sth->fetchrow();
print "$id $name $price\n";

$sth->finish();
$dbh->disconnect();

```

该示例从`Cars`表中为特定的汽车名称选择一行。

```perl
my $name = "Volkswagen"; 

```

这是一个可能来自用户的值。 例如从 HTML 表单。

```perl
my $sth = $dbh->prepare("SELECT * FROM Cars WHERE Name = ?");

```

问号`?`是值的占位符。 它将稍后添加到脚本中。

```perl
$sth->execute($name);

```

在`execute()`方法中，我们将值绑定到占位符。

以下示例与上一个示例相同； 这次我们使用`bind_param()`方法。

```perl
#!/usr/bin/perl

use strict;
use DBI;

my $dbh = DBI->connect(          
    "dbi:SQLite:dbname=test.db", 
    "",                          
    "",                          
    { RaiseError => 1 },         
) or die $DBI::errstr;

my $name = "Volkswagen"; 

my $sth = $dbh->prepare("SELECT * FROM Cars WHERE Name = ?");
$sth->bind_param(1, $name);
$sth->execute();

my ($id, $name, $price) = $sth->fetchrow();
print "$id $name $price\n";

$sth->finish();
$dbh->disconnect();

```

使用`bind_param()`方法检索带有参数绑定的行。

```perl
$sth->bind_param(1, $name);

```

`bind_param()`方法采用一个值，并将其与 SQL 语句内的占位符关联。 可以有更多的占位符。 占位符从 1 开始编号。

## `quote`参数

使用占位符并将参数绑定到它们是处理动态 SQL 语句构建的最佳方法。 有时不能使用占位符。 例如，当我们要动态选择一个表名时。 在这种情况下，我们可以连接 SQL 字符串并使用`quote()`和`quote_identifier()`方法。 我们必须对变量使用这些方法，否则会引入严重的安全性错误。

`quote()`方法引用字符串文字，以用作 SQL 语句中的字面值。 它转义包含在字符串中的任何特殊字符（例如引号），并添加所需类型的外部引号。 `quote_identifier()`方法引用在 SQL 语句中使用的标识符（表名等）。 它转义包含的任何特殊字符（例如双引号），并添加所需类型的外部引号。

```perl
#!/usr/bin/perl

use strict;
use DBI;

my $dbh = DBI->connect(          
    "dbi:SQLite:dbname=test.db", 
    "",                          
    "",                          
    { RaiseError => 1 },         
) or die $DBI::errstr;

my $table = "Cars";
my $name = "Volkswagen";

my $sql = sprintf "SELECT * FROM %s WHERE Name = %s", 
    $dbh->quote_identifier($table), $dbh->quote($name);

my $sth = $dbh->prepare($sql);
$sth->execute();

my @row;
while (@row = $sth->fetchrow_array()) {
    print "@row\n";
}

$sth->finish();
$dbh->disconnect();

```

在该示例中，我们使用`quote()`和`quote_identifier()`方法动态构建 SQL 语句字符串。

```perl
my $table = "Cars";
my $name = "Volkswagen";

```

这些是在 SQL 语句中使用的 Perl 标量。

```perl
my $sql = sprintf "SELECT * FROM %s WHERE Name = %s", 
    $dbh->quote_identifier($table), $dbh->quote($name);

```

我们有一个更复杂的 SQL 语句。 无法使用占位符构建此语句。 我们使用`quote`方法来引用提供的标量。

## 绑定列

使用获取方法时，我们将返回的值复制到 Perl 变量中。 通过绑定列可以简化此过程并使其更快。 Perl DBI 具有`bind_col()`和`bind_columns()`方法，它们将 Perl 变量与表列相关联。

```perl
#!/usr/bin/perl

use strict;
use DBI;

my $dbh = DBI->connect(          
    "dbi:SQLite:dbname=test.db", 
    "",                          
    "",                          
    { RaiseError => 1 },         
) or die $DBI::errstr;

my $sth = $dbh->prepare( "SELECT * FROM Cars LIMIT 4" );  
$sth->execute();

$sth->bind_columns(\my($id, $name, $price));

while ($sth->fetchrow_arrayref()) {
    print "$id $name $price\n";
}

$sth->finish();
$dbh->disconnect();

```

在示例中，我们将`Cars`表的三列绑定到`$id`，`$name`和`$price`变量。

```perl
$sth->bind_columns(\my($id, $name, $price));

```

我们使用`bind_columns()`方法将变量绑定到`Cars`表的列。

```perl
while ($sth->fetchrow_arrayref()) {
    print "$id $name $price\n";
}

```

我们遍历返回的数据并将值打印到控制台。

在 SQLite Perl 教程的这一部分中，我们讨论了绑定参数。