Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Глюк с сохранением записи, сохраняется строка не длинее предыдущей 
:(
    Опции темы
shedon
Дата 16.12.2003, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



Глючит сохранение данных(в OLE DB) присохраненение изменений в строке, новая строка обрезается до размера предыдущей, тоже с добавление новой записи, строки в новой записи обрезаются до размеров, строк в аналогичных полях предыдущей записи.

ЗЫ Извиняюсь за столько вопросов по OLE DB sad.gif


--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
DENNN
Дата 16.12.2003, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



приведи весь код по чтению, записи и инициализации самих аксессоров
PM ICQ   Вверх
shedon
Дата 16.12.2003, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



Для работы стаблицей я пользуюсь кодом сгенерированном мастером, кроме одного я там убрал загрузку БД из строки инициализации

Код

// tblClientInfo.h : Declaration of the CtblClientInfo

#pragma once

#include "Case_ManagementDlg.h"

// code generated on 8 декабря 2003 г., 10:41

class CtblClientInfoAccessor
{
public:
TCHAR m_ClientName[51];
LONG m_ClientID;
TCHAR m_ClientsAddress[51];
TCHAR m_ClientsContactName[51];
LONG m_ClientsContactPhone1;
LONG m_ClientsContactPhone2;
LONG m_ClientsFaxnumber;
CDataSource *_db;

// The following wizard-generated data members contain status
// values for the corresponding fields in the column map. You
// can use these values to hold NULL values that the database
// returns or to hold error information when the compiler returns
// errors. See Field Status Data Members in Wizard-Generated
// Accessors in the Visual C++ documentation for more information
// on using these fields.
// NOTE: You must initialize these fields before setting/inserting data!

DBSTATUS m_dwClientNameStatus;
DBSTATUS m_dwClientIDStatus;
DBSTATUS m_dwClientsAddressStatus;
DBSTATUS m_dwClientsContactNameStatus;
DBSTATUS m_dwClientsContactPhone1Status;
DBSTATUS m_dwClientsContactPhone2Status;
DBSTATUS m_dwClientsFaxnumberStatus;

// The following wizard-generated data members contain length
// values for the corresponding fields in the column map.
// NOTE: For variable-length columns, you must initialize these
//       fields before setting/inserting data!

DBLENGTH m_dwClientNameLength;
DBLENGTH m_dwClientIDLength;
DBLENGTH m_dwClientsAddressLength;
DBLENGTH m_dwClientsContactNameLength;
DBLENGTH m_dwClientsContactPhone1Length;
DBLENGTH m_dwClientsContactPhone2Length;
DBLENGTH m_dwClientsFaxnumberLength;


void GetRowsetProperties(CDBPropSet* pPropSet)
{
 pPropSet->AddProperty(DBPROP_CANFETCHBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
 pPropSet->AddProperty(DBPROP_CANSCROLLBACKWARDS, true, DBPROPOPTIONS_OPTIONAL);
 pPropSet->AddProperty(DBPROP_IRowsetChange, true, DBPROPOPTIONS_OPTIONAL);
 pPropSet->AddProperty(DBPROP_UPDATABILITY, DBPROPVAL_UP_CHANGE | DBPROPVAL_UP_INSERT | DBPROPVAL_UP_DELETE);
}

HRESULT OpenDataSource()
{
//  CDataSource db;
//  HRESULT hr;
// The connection string below may contain plain text passwords and/or
// other sensitive information. Please remove the #error after reviewing
// the connection string for any security related issues. You may want to
// store the password in some other form or use a different user authentication.
 //hr = db.OpenFromInitializationString(L"Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=D:\\Users\\Phil\\Project\\Case_Management\\Case_Management\\Debug\\caseM.mdb;Mode=ReadWrite|Share Deny None;Extended Properties=\"\";Jet OLEDB:System database=\"\";Jet OLEDB:Registry Path=\"\";Jet OLEDB:Database Password=\"\";Jet OLEDB:Engine Type=5;Jet OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password=\"\";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False");
/*  if (FAILED(hr))
 {
#ifdef _DEBUG
  AtlTraceErrorRecords(hr);
#endif
  return hr;
 }*/
 return m_session.Open(*_db);
}

void CloseDataSource()
{
 m_session.Close();
}

operator const CSession&()
{
 return m_session;
}

CSession m_session;

BEGIN_COLUMN_MAP(CtblClientInfoAccessor)
 COLUMN_ENTRY_LENGTH_STATUS(2, m_ClientName, m_dwClientNameLength, m_dwClientNameStatus)
 COLUMN_ENTRY_LENGTH_STATUS(1, m_ClientID, m_dwClientIDLength, m_dwClientIDStatus)
 COLUMN_ENTRY_LENGTH_STATUS(7, m_ClientsAddress, m_dwClientsAddressLength, m_dwClientsAddressStatus)
 COLUMN_ENTRY_LENGTH_STATUS(3, m_ClientsContactName, m_dwClientsContactNameLength, m_dwClientsContactNameStatus)
 COLUMN_ENTRY_LENGTH_STATUS(4, m_ClientsContactPhone1, m_dwClientsContactPhone1Length, m_dwClientsContactPhone1Status)
 COLUMN_ENTRY_LENGTH_STATUS(5, m_ClientsContactPhone2, m_dwClientsContactPhone2Length, m_dwClientsContactPhone2Status)
 COLUMN_ENTRY_LENGTH_STATUS(6, m_ClientsFaxnumber, m_dwClientsFaxnumberLength, m_dwClientsFaxnumberStatus)
END_COLUMN_MAP()
};

class CtblClientInfo : public CTable<CAccessor<CtblClientInfoAccessor> >
{
public:
HRESULT OpenAll()
{
 HRESULT hr;
 hr = OpenDataSource();
 if (FAILED(hr))
  return hr;
 __if_exists(GetRowsetProperties)
 {
  CDBPropSet propset(DBPROPSET_ROWSET);
  __if_exists(HasBookmark)
  {
   propset.AddProperty(DBPROP_IRowsetLocate, true);
  }
  GetRowsetProperties(&propset);
  return OpenRowset(&propset);
 }
 __if_not_exists(GetRowsetProperties)
 {
  __if_exists(HasBookmark)
  {
   CDBPropSet propset(DBPROPSET_ROWSET);
   propset.AddProperty(DBPROP_IRowsetLocate, true);
   return OpenRowset(&propset);
  }
 }
 return OpenRowset();
}

HRESULT OpenRowset(DBPROPSET *pPropSet = NULL)
{
 HRESULT hr = Open(m_session, L"tblClientInfo", pPropSet);
#ifdef _DEBUG
 if(FAILED(hr))
  AtlTraceErrorRecords(hr);
#endif
 return hr;
}

void CloseAll()
{
 Close();
 CloseDataSource();
}
};


Дальше в своей программе я делаю примерно следующее
Код

CDataSource m_db;
CoInitialize(m_db.m_spInit);
if(!FAILED(m_db.Open()))
{
/*
Тут есть небольшой кусок где я получаю коннекшен стринг и сохраняю её в реесре,
а при последующих загрузках запускаюсь из неё
*/
CtblCaseInfo m_oCaseInfoDB;
m_oCaseInfoDB._db = &m_db;
CoInitialize(m_oCaseInfoDB.m_spRowset);
hRes = m_oCaseInfoDB.OpenAll();
if(FAILED(hRes))
{
MessageBox("dBase Failed!!!");
return FALSE;
}
else
{
hRes = m_oCaseInfoDB.MoveFirst();
if(!FAILED(hRes))
 ExchangeData();
else return FALSE;
}
UpdateData(FALSE);
}


Функция ExchangeData(); что-то типа UpdateData();
только если е ей передаю параметр по умалчанию она копирует данные из БД в форму,
передаю true копирует из форму в БД
Вот её пример
Код

void CCaseInfoDlg::ExchangeData(bool bLoad /*=false*/)
{
if(!bLoad)
{
 m_iCaseID = m_oCaseInfoDB.m_CaseID;
 m_iClientID = m_oCaseInfoDB.m_ClientID;
 m_sInvesName = m_oCaseInfoDB.m_InvestigatorName;
 m_oledtDataCaseStart = m_oCaseInfoDB.m_DateStarted;
 m_oledtArrDate = m_oCaseInfoDB.m_InvestigatorArrivalDate;
 m_oledtArrTime = m_oCaseInfoDB.m_InvestigatorArrivalTime;
 m_sClientReq = m_oCaseInfoDB.m_Clientsrequestdescription;
 m_sCaseDesc = m_oCaseInfoDB.m_Casedescription;
 m_sCrimeSceneAddr = m_oCaseInfoDB.m_CrimeSceneAddress;
 m_oledtIncRepDate = m_oCaseInfoDB.m_Dateofincident;
 m_sActivLog = m_oCaseInfoDB.m_ActivityLog;
 m_sSysCont = m_oCaseInfoDB.m_SystemContent;
 m_sCrimeScenDet = m_oCaseInfoDB.m_CrimeScenedetails;
 m_oledtTime = m_oCaseInfoDB.m_Timeofincident;
 m_sReport = m_oCaseInfoDB.m_Whoreportedtheincident;
 UpdateData(bLoad);
}
else
{
 UpdateData(bLoad);
 m_oCaseInfoDB.m_CaseID = m_iCaseID;
 m_oCaseInfoDB.m_ClientID = m_iClientID;
 memset(m_oCaseInfoDB.m_InvestigatorName, 0, sizeof(m_oCaseInfoDB.m_InvestigatorName)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_InvestigatorName, m_sInvesName.AllocSysString(), m_sInvesName.GetLength());

 m_oCaseInfoDB.m_DateStarted = m_oledtDataCaseStart;
 m_oCaseInfoDB.m_InvestigatorArrivalDate = m_oledtArrDate;
 m_oCaseInfoDB.m_InvestigatorArrivalTime = m_oledtArrTime;

 memset(m_oCaseInfoDB.m_Clientsrequestdescription, 0, sizeof(m_oCaseInfoDB.m_Clientsrequestdescription)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_Clientsrequestdescription, m_sClientReq.AllocSysString(), m_sClientReq.GetLength());

 memset(m_oCaseInfoDB.m_Casedescription, 0, sizeof(m_oCaseInfoDB.m_Casedescription)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_Casedescription, m_sCaseDesc.AllocSysString(), m_sCaseDesc.GetLength());

 memset(m_oCaseInfoDB.m_CrimeSceneAddress, 0, sizeof(m_oCaseInfoDB.m_CrimeSceneAddress)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_CrimeSceneAddress, m_sCrimeSceneAddr.AllocSysString(), m_sCrimeSceneAddr.GetLength());

 m_oCaseInfoDB.m_Dateofincident = m_oledtIncRepDate;

 memset(m_oCaseInfoDB.m_ActivityLog, 0, sizeof(m_oCaseInfoDB.m_ActivityLog)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_ActivityLog, m_sActivLog.GetBuffer(), m_sActivLog.GetLength());

 memset(m_oCaseInfoDB.m_SystemContent, 0, sizeof(m_oCaseInfoDB.m_SystemContent)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_SystemContent, m_sSysCont.GetBuffer(), m_sSysCont.GetLength());

 memset(m_oCaseInfoDB.m_CrimeScenedetails, 0, sizeof(m_oCaseInfoDB.m_CrimeScenedetails)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_CrimeScenedetails, m_sCrimeScenDet.GetBuffer(), m_sCrimeScenDet.GetLength());

 memset(m_oCaseInfoDB.m_Whoreportedtheincident, 0, sizeof(m_oCaseInfoDB.m_Whoreportedtheincident)/sizeof(TCHAR));
 memcpy(m_oCaseInfoDB.m_Whoreportedtheincident, m_sReport.GetBuffer(), m_sReport.GetLength());

 m_oCaseInfoDB.m_Timeofincident = m_oledtTime;
}
}

memcpy вроде всё нормально копирует всю строку.
Дальше самое интересное, например если я хочу зменить строку в текущей записи, я вызываю
m_pClientInfo->ExchangeData(true);
m_pClientInfo->m_oClientIfoDB.SetData();

m_pClientInfo->ExchangeData(true) - делает всё нормально копирует как надо,
а вот при вызове m_pClientInfo->m_oClientIfoDB.SetData(); возвращает DB_S_ERRORSOCCURRED



--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
shedon
Дата 16.12.2003, 13:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



[Оказывается я забыл, везде обновлять
m_oClientIfoDB.m_dwClientNameLength = m_sClientName.GetLength();
m_oClientIfoDB.m_dwClientNameStatus = DBSTATUS_S_OK;

Теперь всё работает!!! -smile.gif


--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
DENNN
Дата 16.12.2003, 15:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



лучше сделать:
Код

memset (&m_oClientIfoDB.m_dwClientNameLengt, 0, sizeof(m_oClientIfoDB.m_dwClientNameLengt));
memcpy (.................)

PM ICQ   Вверх
shedon
Дата 16.12.2003, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



DENNN, а что от этого изменится ?


--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
DENNN
Дата 16.12.2003, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



если текстовое поле у тебя объявлено в базе вида char, varchar и т.п., то оно всегда имеет одну и ту же длину - свободные байты должны быть заполнены нулями. Именно так идет обмен данными OLE DB с самой БД - пересылаются все байты. То, что лежит в этих байтах - это твоя задача. Заполнив это поле нулями, а потом вызвав функцию копирования строки, ты можешь быть уверен, что после последнего символа находятся только нулевые байты, либо строка полностью заполнила буфер.
PM ICQ   Вверх
shedon
Дата 16.12.2003, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Экс. модератор
Сообщений: 1209
Регистрация: 17.1.2003
Где: Нижнiй Новгородъ

Репутация: 4
Всего: 11



а разве
memset(m_oCaseInfoDB.m_Whoreportedtheincident, 0, sizeof(m_oCaseInfoDB.m_Whoreportedtheincident)/sizeof(TCHAR));
и
memset (&m_oClientIfoDB.m_dwClientNameLengt, 0, sizeof(m_oClientIfoDB.m_dwClientNameLengt));
не одно и то же ?


--------------------
Programming is like sex: One mistake and you have to support it your lifetime
PM MAIL WWW ICQ   Вверх
DENNN
Дата 16.12.2003, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 3878
Регистрация: 27.3.2002
Где: Москва

Репутация: 1
Всего: 43



Цитата
memset(m_oCaseInfoDB.m_Whoreportedtheincident, 0, sizeof(m_oCaseInfoDB.m_Whoreportedtheincident)/sizeof(TCHAR));

нет.
Цитата
The sizeof operator yields the size of its operand with respect to the size of type char

т.е. тогда уж, следуя твоей логике
Код

sizeof(m_oCaseInfoDB.m_Whoreportedtheincident)/sizeof(char)

TCHAR - введен именно для большей платформонезависимости. Значит, хотя бы теоретически, возможна конфигурация UNICODE, ATL, ... проекта, где тип TCHAR будет не равен 1 байту.
Читаем MSDN:
Цитата
The TCHAR data type is a Win32 character string that can be used to describe ANSI, DBCS, or Unicode strings. For ANSI and DBCS platforms, TCHAR is defined as follows:

typedef char          TCHAR; 
 
For Unicode platforms, TCHAR is defined as synonymous with the WCHAR type.
Что и требовалось доказать. Тем более, что встретить OLE или UNICODE строку в проекте OLE DB - совсем не удивительно.
Можешь также считать, что тип char всегда будет соответствовать 1 байту, поэтому мой код будет выполняться верно всегда.

P.S. CoInitialize вызывается один раз при старте приложения, а при его закрытии должен быть вызван CoUninitialize(NULL);
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0810 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.