Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
Aplicações que realizam uma tarefa fixa geralmente contêm instruções SQL codificadas fixamente. Por exemplo, um sistema de introdução de encomendas pode usar a seguinte chamada para listar ordens de venda abertas:
SQLExecDirect(hstmt, "SELECT OrderID FROM Orders WHERE Status = 'OPEN'", SQL_NTS);
Existem várias vantagens nas instruções SQL codificadas fixamente: podem ser testadas quando a aplicação é escrita; São mais simples de implementar do que as instruções construídas em tempo de execução; E simplificam a aplicação.
Usar parâmetros de instruções e preparar instruções oferece formas ainda melhores de usar instruções SQL codificadas fixamente. Por exemplo, suponha que a tabela de Peças contém as colunas PartID, Description e Price. Uma forma de inserir uma nova linha nesta tabela seria construir e executar uma instrução 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);
Uma forma ainda melhor é usar uma instrução codificada e parametrizada. Isto tem duas vantagens em relação a uma instrução com valores de dados codificados fixamente. Em primeiro lugar, é mais fácil construir uma instrução parametrizada porque os valores dos dados podem ser enviados nos seus tipos nativos, como inteiros e números de vírgula flutuante, em vez de os converter em cadeias. Segundo, tal instrução pode ser usada mais do que uma vez simplesmente alterando os valores dos parâmetros para que a mesma possa ser reexecutada; não é necessário reconstruí-la.
#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);
Assumindo que esta afirmação deve ser executada mais do que uma vez, pode ser preparada para uma eficiência ainda maior:
#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);
Talvez a forma mais eficiente de usar a instrução seja construir um procedimento contendo a sentença, como mostrado no seguinte exemplo de código. Como o procedimento é construído em tempo de desenvolvimento e armazenado na fonte de dados, não precisa de ser preparado em tempo de execução. Uma desvantagem deste método é que a sintaxe para criar procedimentos é específica do SGBD e os procedimentos devem ser construídos separadamente para cada SGBD onde a aplicação vai correr.
#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);
Para mais informações sobre parâmetros, instruções preparadas e procedimentos, consulte Executar uma Instrução.