Parametry instrukcji SQL umożliwiają utworzenie instrukcji SQL wielokrotnego użytku. Jeśli używane są parametry instrukcji, wartości w instrukcji (na przykład wartości dodawane w instrukcji
INSERT
) mogą ulec zmianie, ale podstawowy tekst instrukcji pozostanie niezmieniony. Dlatego użycie parametrów zapewnia potencjalnie wzrost wydajności, a także ułatwia programowanie aplikacji.
Informacje o parametrach instrukcji
Często aplikacja wykorzystuje pojedynczą instrukcję SQL wielokrotnie w aplikacji, z niewielkimi odchyleniami. Na przykład: rozważmy aplikację do wyświetlania zasobów magazynowych, w której użytkownik może dodawać nowe elementy magazynowe do bazy danych. Kod aplikacji, który dodaje element magazynowy do bazy danych wykonuje instrukcję SQL
INSERT
, która w rzeczywistości dodaje dane do bazy danych. Jednak każde wykonanie instrukcji różni się nieznacznie od poprzedniego. Rzeczywiste wartości wprowadzane do tabeli są różne, ponieważ są właściwe dla pozycji magazynowej, która jest dodawana.
W przypadku wielokrotnego korzystania z instrukcji SQL z różnymi wartościami najlepszym podejściem jest użycie instrukcji SQL, która zawiera parametry zamiast wartości literałowych w tekście SQL. Parametr jest elementem zastępczym w tekście instrukcji, który jest zastępowany rzeczywistą wartością przy każdym wykonaniu instrukcji. W celu korzystania z parametrów w instrukcji SQL należy utworzyć instancję klasy
SQLStatement
w standardowy sposób. Dla rzeczywistej instrukcji SQL przypisanej do właściwości
text
należy użyć parametrów zamiast wartości literałowych. Następnie należy zdefiniować wartość dla każdego parametru poprzez ustawienie wartości elementu we właściwości
parameters
instancji SQLStatement. Właściwość
parameters
jest tablicą asocjacyjną, dlatego wartości należy ustawiać za pomocą poniższej składni:
statement.parameters[parameter_identifier] = value;
parameter_identifier
jest ciągiem znaków, jeśli używany jest parametr nazwany, lub wartością całkowitą, jeśli używany jest parametr nienazwany.
Korzystanie z parametrów nazwanych
Parametr może być parametrem nazwanym. Parametr nazwany ma konkretną nazwę, z której korzysta baza danych w celu dopasowania wartości parametru do odpowiedniego elementu zastępczego w tekście instrukcji. Nazwa parametru zawiera znak „:” lub „@”, po którym następuje nazwa, jak w poniższych przykładach:
:itemName
@firstName
Poniższy fragment kodu prezentuje zastosowanie nazwanych parametrów:
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();
Korzystanie z parametrów nienazwanych
Zamiast korzystania z parametrów nazwanych możliwe jest korzystanie z parametrów nienazwanych. W celu użycia parametru nienazwanego należy do instrukcji SQL wprowadzić znak „?”. Do każdego parametru przypisany zostaje indeks liczbowy zgodnie z kolejnością parametrów w instrukcji, począwszy od indeksu 0 dla pierwszego parametru. Poniższy przykład prezentuje wersję poprzedniego przykładu z parametrami nienazwanymi:
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();
Zalety stosowania parametrów
Stosowanie parametrów w instrukcjach SQL zapewnia następujące korzyści:
-
Lepsza wydajność
-
Instancja SQLStatement, w której stosowane są parametry, może zostać wykonana szybciej niż instancja, która dynamicznie tworzy tekst SQL za każdym razem, gdy jest wykonywana. Wzrost wydajności jest spowodowany tym, że instrukcja SQL jest przygotowywana jeden raz i następnie może być wykonywana wielokrotnie przy wykorzystaniu różnych wartości parametrów, bez potrzeby ponownej kompilacji.
-
Jawne określanie typów danych
-
Parametry służą do zastępowania wartości, które nie są znane w momencie konstruowania instrukcji SQL, przez wartości określonego typu. Korzystanie z parametrów to jedyny sposób na to, aby zapewnić klasę zapisu dla wartości przekazanej do bazy danych. Jeśli parametry nie są używane, wówczas środowisko wykonawcze podejmuje próbę konwersji wszystkich wartości z reprezentacji tekstowej na klasę zapisu na podstawie powinowactwa typu skojarzonej kolumny.
Więcej informacji na temat klas zapisu i powinowactwa kolumn można znaleźć w sekcji
Obsługa typów danych
.
-
Większe bezpieczeństwo
-
Korzystanie z parametrów uniemożliwia stosowanie złośliwych technik, takich jak atak SQL inject. W przypadku ataku SQL inject użytkownik wprowadza kod SQL do lokalizacji dostępnej dla użytkownika (np. do pola wprowadzania danych). Jeśli kod aplikacji konstruuje instrukcję SQL poprzez bezpośrednią konkatenację danych wprowadzonych przez użytkownika do postaci tekstu SQL, wówczas kod SQL wprowadzony przez użytkownika jest wykonywany dla bazy danych. Poniższa lista prezentuje przykład konkatenacji danych wprowadzonych przez użytkownika na tekst SQL.
Ta technika nie powinna być stosowana
:
// 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;
Korzystanie z parametrów instrukcji zamiast konkatenowania wartości wprowadzanych przez użytkownika na tekst instrukcji zapobiega atakom typu SQL inject. Atak SQL inject nie jest możliwy, ponieważ wartości parametrów są traktowane jawnie jako podstawiane wartości i nie stają się one częścią literalnego tekstu instrukcji. Poniżej przedstawiono zalecaną alternatywę dla poprzedniego przykładu:
// 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;
|
|
|