Жестко запрограммированные инструкции SQL
Приложения, выполняющие фиксированную задачу, обычно содержат жестко закодированные инструкции SQL. Например, система ввода заказов может использовать следующий вызов для перечисления открытых заказов на продажу:
SQLExecDirect(hstmt, "SELECT OrderID FROM Orders WHERE Status = 'OPEN'", SQL_NTS);
Существует несколько преимуществ для жестко закодированных инструкций SQL: их можно проверить при написании приложения; они проще реализовать, чем инструкции, созданные во время выполнения; и упрощают приложение.
Использование параметров инструкций и подготовка инструкций обеспечивают еще более лучшие способы использования жестко закодированных инструкций SQL. Например, предположим, что таблица "Части" содержит столбцы PartID, Description и Price. Одним из способов вставки новой строки в эту таблицу будет создание и выполнение инструкции INSERT :
#define DESC_LEN 51
#define STATEMENT_LEN 51
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN], Statement[STATEMENT_LEN];
SQLREAL Price;
// Set part ID, description, and price.
GetNewValues(&PartID, Desc, &Price);
// Build INSERT statement.
sprintf_s(Statement, 100, "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (%d, '%s', %f)", PartID, Desc, Price);
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
Еще лучше использовать жестко закодированную параметризованную инструкцию. Это имеет два преимущества по сравнению с оператором с жестко закодированных значений данных. Во-первых, проще создать параметризованную инструкцию, так как значения данных можно отправлять в собственных типах, таких как целые числа и числа с плавающей запятой, а не преобразовывать их в строки. Во-вторых, такой оператор можно использовать несколько раз, просто изменяя значения параметров и повторно изменяя его; Нет необходимости перестроить его.
#define DESC_LEN 51
SQLCHAR * Statement = "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (?, ?, ?)";
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLREAL Price;
SQLINTEGER PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;
// Bind the parameters.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartID, 0, &PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
Desc, sizeof(Desc), &DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&Price, 0, &PriceInd);
// Set part ID, description, and price.
GetNewValues(&PartID, Desc, &Price);
// Execute the statement.
SQLExecDirect(hstmt, Statement, SQL_NTS);
Предполагая, что эта инструкция выполняется несколько раз, она может быть подготовлена к еще большей эффективности:
#define DESC_LEN 51
SQLCHAR *Statement = "INSERT INTO Parts (PartID, Description, Price) "
"VALUES (?, ?, ?)";
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLREAL Price;
SQLINTEGER PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;
// Prepare the INSERT statement.
SQLPrepare(hstmt, Statement, SQL_NTS);
// Bind the parameters.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartID, 0, &PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
Desc, sizeof(Desc), &DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&Price, 0, &PriceInd);
// Loop to continually get new values and insert them.
while (GetNewValues(&PartID, Desc, &Price))
SQLExecute(hstmt);
Возможно, наиболее эффективным способом использования инструкции является создание процедуры, содержащей инструкцию, как показано в следующем примере кода. Так как процедура создается во время разработки и хранится в источнике данных, она не должна быть подготовлена во время выполнения. Недостатком этого метода является то, что синтаксис создания процедур — это субД, и процедуры должны быть созданы отдельно для каждой СУБД, на которой должно выполняться приложение.
#define DESC_LEN 51
SQLUINTEGER PartID;
SQLCHAR Desc[DESC_LEN];
SQLREAL Price;
SQLINTEGER PartIDInd = 0, DescLenOrInd = SQL_NTS, PriceInd = 0;
// Bind the parameters.
SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&PartID, 0, &PartIDInd);
SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, DESC_LEN - 1, 0,
Desc, sizeof(Desc), &DescLenOrInd);
SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_REAL, 7, 0,
&Price, 0, &PriceInd);
// Loop to continually get new values and insert them.
while (GetNewValues(&PartID, Desc, &Price))
SQLExecDirect(hstmt, "{call InsertPart(?, ?, ?)}", SQL_NTS);
Дополнительные сведения о параметрах, подготовленных инструкциях и процедурах см. в разделе "Выполнение инструкции".