TN045: Suporte MFC/banco de dados Varchar Long/Varbinary
Observação |
---|
A seguinte nota técnica não foi atualizada desde que foi incluída pela primeira vez na documentação online.Como resultado, alguns procedimentos e tópicos podem estar desatualizado ou incorreto.As informações mais recentes, é recomendável que você procure o tópico de interesse no índice de documentação on-line. |
Esta nota descreve como recuperar e enviar o ODBC SQL_LONGVARCHAR e SQL_LONGVARBINARY tipos de dados usando o MFC classes de banco de dados.
Visão geral do longa Varchar/Varbinary suporte
O ODBC SQL_LONG_VARCHAR e SQL_LONGBINARY tipos de dados (chamados aqui como colunas de dados longo) podem armazenar enormes quantidades de dados.Existem 3 maneiras de manipular dados:
Bind it to a CString/CByteArray.
Ligar para um CLongBinary.
Não vinculá-lo em todos os e recuperar e enviar o valor de dados longo manualmente, independente das classes de banco de dados.
Cada um dos três métodos tem vantagens e desvantagens.
Colunas de dados longo não há suporte para parâmetros de uma consulta.São suportadas apenas para outputColumns.
Ligação de uma coluna de dados longo a um CString/CByteArray
Vantagens:
Essa abordagem é simple de entender e trabalhar com classes familiares.O framework fornece CFormView suporte para CString com DDX_Text.Há muitas funcionalidades gerais de coleção ou seqüência de caracteres com o CString e CByteArray classes e você pode controlar a quantidade de memória alocada localmente para armazenar o valor de dados.A estrutura mantém uma cópia antiga dos dados de campo durante Editar ou AddNew chamadas de função e estrutura podem detectar automaticamente as alterações dos dados para você.
Observação |
---|
Desde que CString foi projetado para trabalhar em dados de caractere e CByteArray para trabalhar em dados binários, é recomendável que você coloque os dados de caractere (SQL_LONGVARCHAR) em CStringe os dados binários (SQL_LONGVARBINARY) em CByteArray. |
O RFX funções para CString e CByteArray tem um argumento adicional que permite que você substituir o tamanho padrão de memória alocada para armazenar o valor recuperado para a coluna de dados.Observe o argumento de nMaxLength as 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 longo em um CString ou CByteArray, o máximo retornado a quantidade de dados é, por padrão, 255 bytes.Nada além isso é ignorado.Nesse caso, o framework lança a exceção AFX_SQL_ERROR_DATA_TRUNCATED.Felizmente, você pode explicitamente aumentar nMaxLength para valores maiores, até MAXINT.
Observação |
---|
O valor de nMaxLength é usado pelo MFC para definir o buffer do local de SQLBindColumn função.Este é o buffer local para armazenamento de dados e não afeta realmente a quantidade de dados retornados pelo driver ODBC.RFX_Texte RFX_Binary apenas fazer uma chamada usando SQLFetch para recuperar os dados do banco de dados back-end.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 que o valor definido em nMaxLength, caso em que a exceção AFX_SQL_ERROR_DATA_TRUNCATED será lançada.Sob essas circunstâncias, alternar para o uso RFX_LongBinary em vez de RFX_Text ou RFX_Binary para que todos os dados podem ser recuperados. |
ClassWizard irá vincular uma SQL_LONGVARCHAR para um CString, ou um SQL_LONGVARBINARY para um CByteArray para você.Se desejar alocar mais de 255 bytes no qual você recuperar sua coluna de dados long, em seguida, você pode fornecer um valor explícito para nMaxLength.
Quando uma coluna de dados long é ligada a um CString ou CByteArray, atualizando o campo funciona da mesma forma quando é ligado a um SQL_VARCHAR ou SQL_VARBINARY.Durante a Editar, o valor de dados é armazenada em cache longe e posteriormente quando comparado atualização é chamado para detectar alterações nos dados de valor e definir o sujo e valores para a coluna nulos apropriadamente.
Vinculação a uma coluna de dados longo para um CLongBinary
Se a coluna de dados longo pode conter mais MAXINT bytes de dados, você deve provavelmente considerar recuperá-lo em um CLongBinary.
Vantagens:
Recupera uma coluna de dados inteiro longo para a memória disponível.
Desvantagens:
Os dados são mantidos na memória.Essa abordagem também é proibitivamente cara para grandes quantidades de dados.Você deve chamar SetFieldDirty para dados ligados membro para garantir que o campo é incluído em um atualização operação.
Se você recuperar colunas de dados longo em um CLongBinary, as classes de banco de dados Verifique o tamanho total da coluna de dados longo e alocar uma HGLOBAL segmento de memória grande o suficiente para contê-la o valor de dados inteiro.As classes de banco de dados, em seguida, recupere o valor de dados inteiro para o alocado HGLOBAL.
Se a fonte de dados não pode retornar o tamanho esperado da coluna de dados longos, o framework lança a exceção AFX_SQL_ERROR_SQL_NO_TOTAL.Se tentar alocar o HGLOBAL falhar, uma exceção de memória padrão é lançada.
ClassWizard irá vincular uma SQL_LONGVARCHAR ou SQL_LONGVARBINARY para um CLongBinary para você.Selecione CLongBinary como o tipo de variável na caixa de diálogo Adicionar membro variável.ClassWizard adicionará um RFX_LongBinary chamada para seu DoFieldExchange chamar e incrementar o número total de campos acoplados.
Para atualizar valores de coluna de dados longos, verifique primeiro se o alocado HGLOBAL é grande o suficiente para manter seus dados novos chamando :: GlobalSize na m_hData membro do CLongBinary.Se for muito pequeno, liberar o HGLOBAL e aloque um tamanho apropriado.Em seguida, defina m_dwDataLength para refletir o novo tamanho.
Caso contrário, se m_dwDataLength é maior que o tamanho dos dados que você está substituindo, você pode liberar e realocar o HGLOBAL, ou deixe ele alocado.Certifique-se de indicar o número de bytes realmente usadas na m_dwDataLength.
Como atualizar um CLongBinary funciona
Não é necessário compreender como atualizar um CLongBinary funciona, mas pode ser útil como um exemplo de como enviar valores de dados longos para uma fonte de dados, se você escolher esse método terceiro, descrito abaixo.
Observação |
---|
Para que um CLongBinary campo a ser incluído em uma atualização, você deve chamar explicitamente SetFieldDirty para o campo.Se você fizer qualquer alteração a um campo, incluindo a definição de Null, você deve 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 do ODBC de usar DATA_AT_EXEC mecanismo (consulte a documentação do ODBC em SQLSetPosdo argumento rgbValue).Quando o framework prepara a instrução insert ou update, em vez de apontar para o HGLOBAL que contém os dados a endereço do CLongBinary é definido como o valor da coluna em vez disso e o indicador de comprimento definido para SQL_DATA_AT_EXEC.Mais tarde, quando a instrução update é enviada para a fonte de dados, SQLExecDirect retornará SQL_NEED_DATA.Isso avisa que a estrutura que o valor de parâmetro para esta coluna é realmente o endereço de um CLongBinary.O framework chama SQLGetData uma vez com um buffer pequeno esperando o driver para retornar o comprimento real dos dados.Se o driver retorna o comprimento real do objeto binário grande (BLOB), MFC realoca o espaço necessário para buscar o BLOB.Se a fonte de dados retorna SQL_NO_TOTAL, indicando que não é possível determinar o tamanho do BLOB, MFC irá criar blocos menores.O tamanho inicial padrão é 64K e blocos subseqüentes será o dobro do tamanho; Por exemplo, a segunda será de 128 K, o terceiro é de 256 K e assim por diante.O tamanho inicial é configurável.
Não vinculação: Recuperando/enviando dados diretamente do ODBC com SQLGetData
Com esse método você completamente ignorar as classes de banco de dados e lida com a coluna de dados longos.
Vantagens:
Você pode armazenar em cache dados em disco se necessário, ou decidir dinamicamente a quantidade de dados para recuperar.
Desvantagens:
Você não obtém a estrutura Editar ou AddNew suporte e você deve escrever código para executar a funcionalidade básica (Excluir trabalhar, pois não é uma operação de nível de coluna).
Nesse caso, a coluna de dados longo deve estar na lista de seleção do conjunto de registros, mas não deve ser acoplada pela estrutura.Uma forma de fazer isso é fornecer sua própria instrução SQL via GetDefaultSQL ou como o argumento lpszSQL CRecordsetdo Abrir de função e não ligar a coluna extra com uma chamada de função RFX_.ODBC requer que os campos não acoplados aparecem à direita dos campos acoplados, para adicionar a coluna não acoplada ou colunas no final da lista de seleção.
Observação |
---|
Porque a coluna de dados longo não é vinculada pela estrutura, as alterações não serão tratadas com CRecordset::Update chamadas.Você deve criar e enviar SQL necessária Inserir e atualização instruções sozinho. |