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.
Observação
A nota técnica a seguir não foi atualizada desde que foi incluída pela primeira vez na documentação on-line. Como resultado, alguns procedimentos e tópicos podem estar desatualizados ou incorretos. Para obter as informações mais recentes, recomenda-se que pesquise o tópico de interesse no índice de documentação online.
Esta nota descreve como recuperar e enviar os tipos de dados ODBC SQL_LONGVARCHAR e SQL_LONGVARBINARY usando as classes de banco de dados MFC.
Visão geral do suporte Long Varchar/Varbinary
Os tipos de dados ODBC SQL_LONG_VARCHAR e SQL_LONGBINARY (referidos aqui como colunas de dados longas) podem conter grandes quantidades de dados. Existem 3 formas de lidar com estes dados:
Vincule-o a um
CString/CByteArrayarquivo .Vincule-o a um
CLongBinary.Não o vincule de forma alguma e recupere e envie o valor de dados longos manualmente, independentemente das classes de banco de dados.
Cada um dos três métodos tem vantagens e desvantagens.
Não há suporte para colunas de dados longas para parâmetros de uma consulta. Eles são suportados apenas para outputColumns.
Vinculando uma coluna de dados longa a um CString/CByteArray
Vantagens:
Essa abordagem é simples de entender e você trabalha com classes familiares. A estrutura fornece CFormView suporte para CString com DDX_Text. Você tem muitas funcionalidades gerais de cadeia de caracteres ou coleção com as CString classes e CByteArray e pode controlar a quantidade de memória alocada localmente para armazenar o valor dos dados. A estrutura mantém uma cópia antiga dos dados de campo durante chamadas de função Edit ou AddNew, e a estrutura pode detetar automaticamente alterações nos dados para si.
Observação
Como CString foi projetado para trabalhar em dados de caracteres e CByteArray para trabalhar em dados binários, é recomendável que você coloque os dados de caractere (SQL_LONGVARCHAR) em CString, e os dados binários (SQL_LONGVARBINARY) em CByteArray.
As funções RFX para CString e CByteArray têm um argumento adicional que permite substituir o tamanho padrão da memória alocada para manter o valor recuperado para a coluna de dados. Observe o argumento nMaxLength nas seguintes declarações de função:
void AFXAPI RFX_Text(CFieldExchange* pFX,
const char *szName,
CString& value,
int nMaxLength = 255,
int nColumnType =
SQL_VARCHAR);
void AFXAPI RFX_Binary(CFieldExchange* pFX,
const char *szName,
CByteArray& value,
int nMaxLength = 255);
Se você recuperar uma coluna de dados longa em um CString ou CByteArray, a quantidade máxima retornada de dados será, por padrão, 255 bytes. Qualquer coisa além disso é ignorada. Nesse caso, a estrutura lançará a exceção AFX_SQL_ERROR_DATA_TRUNCATED. Felizmente, você pode aumentar explicitamente nMaxLength para valores maiores, até MAXINT.
Observação
O valor de nMaxLength é usado pelo MFC para definir o SQLBindColumn buffer local da função. Este é o buffer local para armazenamento dos dados e não afeta a quantidade de dados retornados pelo driver ODBC.
RFX_Text e RFX_Binary fazem apenas uma chamada usando SQLFetch para recuperar os dados do backend. Cada driver ODBC tem uma limitação diferente na quantidade de dados que eles podem retornar em uma única busca. Esse limite pode ser muito menor do que o valor definido em nMaxLength, caso em que a exceção AFX_SQL_ERROR_DATA_TRUNCATED será lançada. Nessas circunstâncias, mude para usar RFX_LongBinary em vez de RFX_Text ou RFX_Binary para que todos os dados possam ser recuperados.
O ClassWizard associará um SQL_LONGVARCHAR a um CString, ou um SQL_LONGVARBINARY a um CByteArray para você. Se quiser alocar mais de 255 bytes nos quais você recupera sua coluna de dados longa, você pode fornecer um valor explícito para nMaxLength.
Quando uma coluna de dados longa é vinculada a um CString ou CByteArray, a atualização do campo funciona exatamente como quando ele está vinculado a um SQL_VARCHAR ou SQL_VARBINARY. Durante Edit, o valor dos dados é armazenado em cache e posteriormente comparado quando Update é chamado para detetar alterações no valor dos dados e definir os valores Sujo e Nulo para a coluna adequadamente.
Vinculando uma coluna de dados longa a um CLongBinary
Se a sua coluna de dados longa pode conter mais dados do que o limite de bytes MAXINT, deve provavelmente considerar recuperá-la num CLongBinary.
Vantagens:
Isso recupera uma coluna de dados longa inteira, até a memória disponível.
Desvantagens:
Os dados são mantidos na memória. Esta abordagem é também proibitivamente dispendiosa para grandes quantidades de dados. Você deve chamar o SetFieldDirty membro de dados vinculado para garantir que o campo seja incluído numa operação Update.
Se você recuperar colunas de dados longas em um CLongBinary, as classes de banco de dados verificarão o tamanho total da coluna de dados longas e, em seguida, alocarão um HGLOBAL segmento de memória grande o suficiente para armazenar todo o valor de dados. Em seguida, as classes de banco de dados recuperam todo o valor de dados no local alocado HGLOBAL.
Se a fonte de dados não puder retornar o tamanho esperado da coluna de dados longa, a estrutura lançará a exceção AFX_SQL_ERROR_SQL_NO_TOTAL. Se a tentativa de alocar o HGLOBAL falhar, uma exceção de memória padrão será lançada.
O ClassWizard associará um SQL_LONGVARCHAR ou SQL_LONGVARBINARY a um CLongBinary para você. Selecione CLongBinary como Tipo de variável na caixa de diálogo Adicionar variável de membro. O ClassWizard adicionará uma RFX_LongBinary chamada à sua DoFieldExchange chamada e incrementará o número total de campos vinculados.
Para atualizar os valores de colunas extensas de dados, primeiro verifique se a alocação HGLOBAL é grande o suficiente para armazenar os seus novos dados chamando ::GlobalSize no membro m_hData do CLongBinary. Se for muito pequeno, solte o HGLOBAL e aloque um no tamanho apropriado. Em seguida, defina m_dwDataLength para refletir o novo tamanho.
Caso contrário, se m_dwDataLength for maior do que o tamanho dos dados que você está substituindo, você pode liberar e realocar o HGLOBAL, ou deixá-lo alocado. Certifique-se de indicar o número de bytes realmente usados em m_dwDataLength.
Como funciona a atualização de um CLongBinary
Não é necessário entender como a atualização de um CLongBinary funciona, mas pode ser útil como um exemplo sobre como enviar valores de dados longos para uma fonte de dados, se você escolher este terceiro método, descrito abaixo.
Observação
Para que um CLongBinary campo seja incluído numa atualização, deve chamar explicitamente SetFieldDirty para o campo. Se você fizer qualquer alteração em um campo, incluindo defini-lo como Nulo, deverá chamar SetFieldDirty. Você também deve chamar SetFieldNull, com o segundo parâmetro sendo FALSE, para marcar o campo como tendo um valor.
Ao atualizar um CLongBinary campo, as classes de banco de dados usam o mecanismo de DATA_AT_EXEC do ODBC (consulte a documentação do ODBC no SQLSetPosargumento rgbValue do ). Quando o framework prepara a instrução de insert ou update, em vez de apontar para o HGLOBAL que contém os dados, o endereço do CLongBinary é definido como o valor da coluna, e o indicador de comprimento é definido como SQL_DATA_AT_EXEC. Mais tarde, quando a instrução de atualização for enviada para a fonte de dados, SQLExecDirect retornará SQL_NEED_DATA. Isso alerta a estrutura de que o valor do param para esta coluna é, na verdade, o endereço de um CLongBinary. O framework chama SQLGetData uma vez com um pequeno buffer, esperando que o driver retorne o comprimento real dos dados. Se o driver retornar o comprimento real do objeto binário grande (o BLOB), o MFC realocará tanto espaço quanto necessário para buscar o BLOB. Se a fonte de dados retornar SQL_NO_TOTAL, indicando que não pode determinar o tamanho do BLOB, o MFC criará blocos menores. O tamanho inicial padrão é 64K, e os blocos subsequentes terão o dobro do tamanho; por exemplo, o segundo será 128K, o terceiro será 256K, e assim por diante. O tamanho inicial é configurável.
Não vinculativo: recuperação/envio de dados diretamente do ODBC com SQLGetData
Com esse método, você ignora completamente as classes de banco de dados e lida com a coluna de dados longa por conta própria.
Vantagens:
Você pode armazenar dados em cache no disco, se necessário, ou decidir dinamicamente a quantidade de dados a ser recuperada.
Desvantagens:
Você não obtém o suporte da estrutura de Edit ou AddNew, e deve escrever código você mesmo para executar a funcionalidade básica (no entanto, Delete funciona, uma vez que não é uma operação de nível de coluna).
Nesse caso, a coluna de dados longa deve estar na lista de seleção do conjunto de registros, mas não deve ser vinculada pela estrutura. Uma maneira de fazer isso é fornecer a sua própria instrução SQL via GetDefaultSQL ou como argumento lpszSQL para a função CRecordset, Open, e não associar a coluna extra com uma chamada de função RFX_. O ODBC requer que os campos não acoplados apareçam à direita dos campos acoplados, portanto, adicione sua coluna ou colunas não acopladas ao final da lista de seleção.
Observação
Como sua coluna de dados longa não está vinculada pela estrutura, as alterações nela não serão tratadas com CRecordset::Update chamadas. Você mesmo deve criar e enviar as instruções SQL INSERT e UPDATE necessárias.