在陳述式中使用參數

Adobe AIR 1.0 以及更新的版本

使用 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:String =  
    "INSERT INTO inventoryItems (name, productCode)" + 
    "VALUES (:name, :productCode)"; 
     
var addItemStmt:SQLStatement = new 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:String =  
    "INSERT INTO inventoryItems (name, productCode)" + 
    "VALUES (?, ?)"; 
     
var addItemStmt:SQLStatement = new SQLStatement(); 
addItemStmt.sqlConnection = conn; 
addItemStmt.text = sql; 
     
// set parameter values 
addItemStmt.parameters[0] = "Item name"; 
addItemStmt.parameters[1] = "12345"; 
     
addItemStmt.execute(); 

使用參數的優點

在 SQL 陳述式中使用參數有多項優點:

效能更佳
使用參數的 SQLStatement 實體執行起來會比在每次執行時以動態方式建立 SQL 文字的實體更有效率。效能改進的最大原因在於,陳述式只會準備一次,之後就能使用不同的參數值執行多次,而不必重新編譯 SQL 陳述式。

明確的資料輸入
使用參數後,便可以將建構 SQL 陳述式時未知的值取代為所輸入資料。使用參數是唯一可確保傳入資料庫之值使用儲存類別的方式。如果不使用參數,執行階段會嘗試將所有的值根據關聯欄的類型相似性,從文字形式轉換成儲存類別。

如需儲存類別和欄相似性的詳細資訊,請參閱資料類型支援

更高的安全性
使用參數可協助避免稱為 SQL 插入式攻擊的惡意技巧。在 SQL 插入式攻擊中,使用者會在使用者可存取的位置 (例如,資料輸入欄位) 輸入 SQL 程式碼。如果應用程式程式碼是直接將使用者輸入連接至 SQL 文字中以建構 SQL 陳述式,則使用者所輸入的 SQL 程式碼會針對資料庫來執行。以下列出的程式碼會示範將使用者輸入連接至 SQL 文字中的範例,請勿使用此技巧
// assume the variables "username" and "password" 
// contain user-entered data 
     
var sql:String = 
    "SELECT userId " + 
    "FROM users " + 
    "WHERE username = '" + username + "' " + 
    "    AND password = '" + password + "'"; 
     
var statement:SQLStatement = new SQLStatement(); 
statement.text = sql; 

使用陳述式參數來取代將使用者輸入值連接至陳述式的文字,可以防止 SQL 插入式攻擊。由於參數值會視為明確的替代值,而不是陳述式文字常值的一部分,因此不會發生 SQL 插入。以下為上述程式碼範例的建議替代方式:

// assume the variables "username" and "password" 
// contain user-entered data 
     
var sql:String = 
    "SELECT userId " + 
    "FROM users " + 
    "WHERE username = :username " + 
    "    AND password = :password"; 
     
var statement:SQLStatement = new SQLStatement(); 
statement.text = sql; 
     
// set parameter values 
statement.parameters[":username"] = username; 
statement.parameters[":password"] = password;