Dados Long e SQLSetPos e SQLBulkOperations

Como é o caso com parâmetros em instruções SQL, dados longos podem ser enviados ao atualizar linhas com SQLBulkOperations ou SQLSetPos ou ao inserir linhas com SQLBulkOperations. Os dados são enviados em partes, com diversas chamadas para SQLPutData. As colunas para as quais os dados são enviados no tempo de execução são conhecidas como colunas de dados em execução.

Observação

Um aplicativo realmente pode enviar qualquer tipo de dado em tempo de execução com SQLPutData, embora apenas dados de caracteres e binários possam ser enviados em partes. Porém, se os dados forem pequenos o suficiente para caber em um só buffer, geralmente não haverá razão para usar SQLPutData. É muito mais fácil associar o buffer e permitir que o driver recupere os dados do buffer.

Como colunas de dados longas normalmente não são associadas, o aplicativo deve associar a coluna antes de chamar SQLBulkOperations ou SQLSetPos e desvinculá-la depois de chamar SQLBulkOperations ou SQLSetPos. A coluna deve ser associada porque SQLBulkOperations ou SQLSetPos opera apenas em colunas associadas e deve ser desassociada para que SQLGetData possa ser usado para recuperar dados da coluna.

Para enviar dados em tempo de execução, o aplicativo faz isto:

  1. Coloca um valor de 32 bits no buffer do conjunto de linhas, em vez de um valor de dados. Esse valor será retornado ao aplicativo posteriormente, portanto, o aplicativo deverá defini-lo como um valor significativo, como o número da coluna ou o identificador de um arquivo que contém dados.

  2. Define o valor no buffer de comprimento/indicador como o resultado da macro SQL_LEN_DATA_AT_EXEC(length). Esse valor indica ao driver que os dados para o parâmetro serão enviados com SQLPutData. O valor de comprimento é usado ao enviar dados longos para uma fonte de dados que precisa saber quantos bytes de dados longos serão enviados para pré-alocar espaço. Para determinar se uma fonte de dados precisa desse valor, o aplicativo chama SQLGetInfo com a opção SQL_NEED_LONG_DATA_LEN. Todos os drivers devem dar suporte a essa macro. Se a fonte de dados não exigir o comprimento do byte, o driver poderá ignorá-lo.

  3. Chama SQLBulkOperations ou SQLSetPos. O driver descobre que um buffer de comprimento/indicador contém o resultado da macro SQL_LEN_DATA_AT_EXEC(length) e retorna SQL_NEED_DATA como o valor retornado da função.

  4. Chama SQLParamData em resposta ao valor retornado SQL_NEED_DATA. Se for necessário enviar dados longos, SQLParamData retornará SQL_NEED_DATA. No buffer apontado pelo argumento ValuePtrPtr , o driver retorna o valor exclusivo que o aplicativo colocou no buffer do conjunto de linhas. Se houver mais de uma coluna de dados em execução, o aplicativo usará esse valor para determinar para qual coluna enviar dados. O driver não é obrigado a solicitar dados para colunas de dados em execução em nenhuma ordem específica.

  5. Chama SQLPutData para enviar os dados da coluna para o driver. Se os dados da coluna não se encaixarem em um só buffer, como geralmente é o caso com dados longos, o aplicativo chamará SQLPutData repetidamente para enviar os dados em partes. Cabe ao driver e à fonte de dados remontar os dados. Se o aplicativo passar dados de cadeia de caracteres terminados em nulo, o driver ou a fonte de dados deverá remover o caractere de terminação nula como parte do processo de remontagem.

  6. Chama SQLParamData novamente para indicar que enviou todos os dados para a coluna. Se houver colunas de dados em execução para as quais os dados não foram enviados, o driver retornará SQL_NEED_DATA e o valor exclusivo para a próxima coluna de dados em execução. O aplicativo retorna à etapa 5. Se os dados tiverem sido enviados para todas as colunas de dados em execução, os dados da linha serão enviados para a fonte de dados. O SQLParamData então retorna SQL_SUCCESS ou SQL_SUCCESS_WITH_INFO e pode retornar qualquer SQLSTATE que SQLBulkOperations ou SQLSetPos possa retornar.

Depois que SQLBulkOperations ou SQLSetPos retorna SQL_NEED_DATA e antes que os dados tenham sido completamente enviados para a última coluna de dados em execução, a instrução está em um estado Requer Dados. Nesse estado, o aplicativo pode chamar apenas SQLPutData, SQLParamData, SQLCancel, SQLGetDiagField ou SQLGetDiagRec. Todas as outras funções retornam SQLSTATE HY010 (erro de sequência de função). Chamar SQLCancel cancela a execução da instrução e a retorna ao seu estado anterior. Para obter mais informações, confira o Apêndice B: Tabelas de transição de estado do ODBC.