Executar uma instrução
Há quatro maneiras de executar uma instrução, dependendo de quando ela é compilada (preparada) pelo mecanismo de banco de dados e quem a define:
Execução direta O aplicativo define a instrução SQL. Ela é preparada e executada em tempo de execução em etapas separadas.
Execução preparada O aplicativo define a instrução SQL. Ele é preparado e executado em tempo de execução em etapas separadas. A declaração pode ser preparada uma vez e executada várias.
Procedimentos O aplicativo pode definir e compilar uma ou mais instruções SQL em tempo de desenvolvimento e armazená-las na fonte de dados como um procedimento. O procedimento é executado uma vez ou mais em tempo de execução. O aplicativo pode enumerar os procedimentos armazenados disponíveis usando funções de catálogo.
Funções de catálogo O gravador de driver cria uma função que retorna um conjunto de resultados predefinido. Normalmente, essa função envia uma instrução SQL predefinida ou chama um procedimento criado para esse fim. A função é executada uma vez ou mais em tempo de execução.
Uma determinada instrução (conforme identificada pelo seu identificador de instrução) pode ser executada qualquer número de vezes. A instrução pode ser executada com uma variedade de instruções SQL distintas ou pode ser executada repetidamente com a mesma instrução SQL. Como um exemplo, o código a seguir usa o mesmo identificador de instrução (hstmt1) para recuperar e exibir as tabelas no banco de dados Sales. Ele então reutiliza esse identificador para recuperar as colunas em uma tabela selecionada pelo usuário.
SQLHSTMT hstmt1;
SQLCHAR * Table;
// Create a result set of all tables in the Sales database.
SQLTables(hstmt1, "Sales", SQL_NTS, "sysadmin", SQL_NTS, NULL, 0, NULL, 0);
// Fetch and display the table names; then close the cursor.
// Code not shown.
// Have the user select a particular table.
SelectTable(Table);
// Reuse hstmt1 to create a result set of all columns in Table.
SQLColumns(hstmt1, "Sales", SQL_NTS, "sysadmin", SQL_NTS, Table, SQL_NTS, NULL, 0);
// Fetch and display the column names in Table; then close the cursor.
// Code not shown.
E o código a seguir mostra como um só identificador é usado para executar repetidamente a mesma instrução para excluir linhas de uma tabela.
SQLHSTMT hstmt1;
SQLUINTEGER OrderID;
SQLINTEGER OrderIDInd = 0;
// Prepare a statement to delete orders from the Orders table.
SQLPrepare(hstmt1, "DELETE FROM Orders WHERE OrderID = ?", SQL_NTS);
// Bind OrderID to the parameter for the OrderID column.
SQLBindParameter(hstmt1, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0,
&OrderID, 0, &OrderIDInd);
// Repeatedly execute hstmt1 with different values of OrderID.
while ((OrderID = GetOrderID()) != 0) {
SQLExecute(hstmt1);
}
Para muitos drivers, alocar instruções é uma tarefa dispendiosa, portanto, reutilizar a mesma instrução dessa maneira costuma ser mais eficiente do que liberar instruções existentes e alocar novas. Os aplicativos que criam conjuntos de resultados em uma instrução devem ter o cuidado de fechar o cursor sobre o conjunto de resultados antes de executar novamente a instrução; para obter mais informações, confira Como fechar o cursor.
Reutilizar instruções também força o aplicativo a evitar uma limitação em alguns drivers do número de instruções que podem estar ativas ao mesmo tempo. A definição exata de "ativo" é específica do driver, mas costuma se referir a qualquer declaração que tenha sido preparada ou executada e ainda tenha resultados disponíveis. Por exemplo, depois que uma instrução INSERT foi preparada, ela é geralmente considerada ativa; depois que uma instrução SELECT foi executada e o cursor ainda está aberto, ela geralmente é considerada ativa; depois que uma instrução CREATE TABLE foi executada, ela geralmente não é considerada ativa.
Um aplicativo determina quantas instruções podem estar ativas em uma só conexão ao mesmo tempo chamando SQLGetInfo com a opção SQL_MAX_CONCURRENT_ACTIVITIES. Um aplicativo pode usar mais instruções ativas do que esse limite abrindo várias conexões com a fonte de dados. Como as conexões podem ser dispendiosas, é preciso considerar o efeito sobre o desempenho.
Os aplicativos podem limitar a quantidade de tempo alocada para que uma instrução seja executada com o atributo de instrução SQL_ATTR_QUERY_TIMEOUT. Se o período de tempo limite expirar antes de a fonte de dados retornar o conjunto de resultados, a função que executa a instrução SQL retornará SQLSTATE HYT00 (Tempo limite expirou). Por padrão, não há nenhum tempo limite.
Esta seção contém os tópicos a seguir.