使用 SQL 语句参数,您可以创建可重用的 SQL 语句。使用语句参数时,语句中的值可以更改(如在
INSERT
语句中添加的值),但是基本的语句文本保持不变。所以,使用参数可提供性能优势,并且可以更轻松地进行应用程序编码。
了解语句参数
应用程序经常在自身中多次使用单个 SQL 语句,只是稍有不同。以一个库存跟踪应用程序为例,用户可以在其中向数据库添加新的库存项目。向数据库添加库存项目的应用程序代码执行 SQL
INSERT
语句,该语句实际上向数据库添加数据。但是,每次执行该语句时都稍有不同。具体来说,在表中插入的实际值是不同的,因为它们特定于所添加的库存项目。
在多次使用一个 SQL 语句但该语句中的值不同的情况下,最佳方法是使用包括参数的 SQL 语句而不是在 SQL 文本中包括字面值。参数是语句文本中的一个占位符,每次执行语句时都将它替换为实际的值。要在 SQL 语句中使用参数,请像通常一样创建
SQLStatement
实例。对于分配给
text
属性的实际 SQL 语句,使用参数占位符而不是字面值。然后通过在 SQLStatement 实例的
parameters
属性中设置元素值来定义每个参数的值。
parameters
属性是一个关联数组,所以需要使用以下语法设置特殊值:
statement.parameters[parameter_identifier] = value;
如果使用命名参数,则
parameter_identifier
是字符串;如果使用未命名参数,则它是整数索引。
使用命名参数
参数可以是命名参数。命名参数具有一个特定的名称,数据库使用该名称将参数值与语句文本中其占位符位置相匹配。参数名称由“:”或“@”字符后跟一个名称组成,如以下示例所示:
:itemName
@firstName
以下代码清单演示命名参数的用法:
var sql =
"INSERT INTO inventoryItems (name, productCode)" +
"VALUES (:name, :productCode)";
var addItemStmt = new air.SQLStatement();
addItemStmt.sqlConnection = conn;
addItemStmt.text = sql;
// set parameter values
addItemStmt.parameters[":name"] = "Item name";
addItemStmt.parameters[":productCode"] = "12345";
addItemStmt.execute();
使用未命名参数
作为使用命名参数的一种替代方式,也可以使用未命名参数。若要使用未命名参数,请使用“?”字符表示 SQL 语句中的参数。按照参数在语句中的顺序,每个参数都分配有一个数字索引,数字索引从索引 0(表示第一个参数)开始。以下示例使用未命名参数演示上述示例的一个版本:
var sql =
"INSERT INTO inventoryItems (name, productCode)" +
"VALUES (?, ?)";
var addItemStmt = new air.SQLStatement();
addItemStmt.sqlConnection = conn;
addItemStmt.text = sql;
// set parameter values
addItemStmt.parameters[0] = "Item name";
addItemStmt.parameters[1] = "12345";
addItemStmt.execute();
使用参数的优点
在 SQL 语句中使用参数有以下几个优点:
-
性能更佳
-
与每次执行时动态创建 SQL 文本的 SQLStatement 实例相比,使用参数的 SQLStatement 实例可以更高效地执行。性能之所以得到提高,是因为只准备一次语句,然后可以使用不同的参数值多次执行它,而无需重新编译 SQL 语句。
-
显式数据类型指定
-
参数用于允许对构造 SQL 语句时未知的值进行类型替代。使用参数是保证将值的存储类传递到数据库的唯一方式。不使用参数时,运行时会尝试根据相关联列的类型关联将所有值从其文本表示形式转换为存储类。
有关存储类和列关联的详细信息,请参阅
数据类型支持
。
-
安全性更高
-
使用参数有助于防止恶意技术攻击(称为 SQL 注入攻击)。在 SQL 注入攻击中,用户在用户可访问的位置(例如数据输入字段)输入 SQL 代码。如果应用程序代码通过将用户输入直接连接到 SQL 文本来构造 SQL 语句,则将对数据库执行用户输入的 SQL 代码。下面的列表显示将用户输入连接到 SQL 文本的示例。
不要使用此技术
:
// assume the variables "username" and "password"
// contain user-entered data
var sql =
"SELECT userId " +
"FROM users " +
"WHERE username = '" + username + "' " +
" AND password = '" + password + "'";
var statement = new air.SQLStatement();
statement.text = sql;
使用语句参数而不是将用户输入的值连接到语句的文本中,可防止 SQL 注入攻击。SQL 注入无法发生的原因是,系统将参数值明确视为替代值,而不是作为字面语句文本的一部分。下面是对前面列表的建议替代方法:
// assume the variables "username" and "password"
// contain user-entered data
var sql =
"SELECT userId " +
"FROM users " +
"WHERE username = :username " +
" AND password = :password";
var statement = new air.SQLStatement();
statement.text = sql;
// set parameter values
statement.parameters[":username"] = username;
statement.parameters[":password"] = password;
|
|
|