# 绑定参数

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

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

当我们绑定参数时，我们在语句中创建占位符。 占位符是 SQL 语句中的特殊标记。 它通常是一个问号`?`。 稍后，使用`bind_param`，`execute`，`query`等方法将参数绑定到占位符。 绑定参数可以防止 SQL 注入程序。 它会自动转义一些特殊字符并允许正确处理它们。

准备语句并在执行语句之前绑定其参数时，通常可以提高数据库性能。 在`sqlite3` Ruby 模块中，始终准备语句。 即使我们不调用数据库对象的`prepare`方法而直接调用`execute`方法，该语句也是由`sqlite3` Ruby 模块在后台准备的。

```ruby
#!/usr/bin/ruby

require 'sqlite3'

begin

    db = SQLite3::Database.new "test.db"

    name = "Volkswagen"

    stm = db.prepare "SELECT * FROM Cars WHERE Name = ?"
    stm.bind_param 1, name
    rs = stm.execute

    row = rs.next    
    puts row.join "\s"

rescue SQLite3::Exception => e 

    puts "Exception occurred"
    puts e

ensure
    stm.close if stm
    db.close if db
end

```

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

```ruby
name = "Volkswagen"

```

此值可能来自用户：例如，来自 HTML 表单。

```ruby
stm = db.prepare "SELECT * FROM Cars WHERE Name = ?"

```

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

```ruby
stm.bind_param 1, name
rs = stm.execute

```

使用`bind_param`方法，名称变量与语句中的占位符关联。 `execute`方法将返回结果集。

```ruby
$ ./bindparam1.rb 
8 Volkswagen 21600

```

这是示例的输出。

接下来，我们提出另一种绑定参数的方式。

```ruby
#!/usr/bin/ruby

require 'sqlite3'

begin

    db = SQLite3::Database.new "test.db"

    id = 4

    stm = db.prepare "SELECT * FROM Cars WHERE Id = :id"
    rs = stm.execute id

    row = rs.next    
    puts row.join "\s"

rescue SQLite3::Exception => e 

    puts "Exception occurred"
    puts e

ensure
    stm.close if stm
    db.close if db
end

```

我们从`Cars`表中为特定 ID 选择一行。

```ruby
stm = db.prepare "SELECT * FROM Cars WHERE Id = :id"

```

以前，我们已经看到一个问号作为占位符。 SQLite Ruby 也支持命名占位符。

```ruby
rs = stm.execute id

```

该参数绑定在`execute`方法中。

我们提供了另一种绑定参数的方法。

```ruby
#!/usr/bin/ruby

require 'sqlite3'

begin

    db = SQLite3::Database.new "test.db"

    id = 3
    row = db.get_first_row "SELECT * FROM Cars WHERE Id = ?", id       
    puts row.join "\s"

rescue SQLite3::Exception => e 

    puts "Exception occurred"
    puts e

ensure
    db.close if db
end

```

这次，所有事情（准备语句，绑定参数和执行语句）都使用一种方法完成。

```ruby
row = db.get_first_row "SELECT * FROM Cars WHERE Id = ?", id    

```

`get_first_row`是一种便捷的方法，一步完成三件事。

在最后一个示例中，我们将在一个语句中绑定多个参数。

```ruby
#!/usr/bin/ruby

require 'sqlite3'

begin

    db = SQLite3::Database.new ":memory:"

    stm = db.prepare "SELECT 2 + ? + 6 + ? + ?"
    stm.bind_params 3, 4, 6
    rs = stm.execute

    row = rs.next    
    puts row

rescue SQLite3::Exception => e 

    puts "Exception occurred"
    puts e

ensure
    stm.close if stm
    db.close if db
end

```

在该示例中，SQL 语句中有更多的占位符。

```ruby
stm = db.prepare "SELECT 2 + ? + 6 + ? + ?"

```

`SELECT`语句中有三个占位符。

```ruby
stm.bind_params 3, 4, 6

```

我们用`bind_params`方法绑定三个值。

```ruby
$ ./bindparams.rb
21

```

这是`bindparams.rb`程序的输出。

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