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.