[MFC + MSSQL] Nieprawidłowy indeks deskryptora

0

Witam!

Prubuję napisać program, który będzie potrafił zapisywać i pobierać z bazy MS SQL obraz (typ image). Jadnek przy próbie połączenia, wyskakuje błąd "Nieprawidłowy indeks deskryptora". A więc po kolei...

Najpierw napiasłem program, który operuje na typach liczbowych, tekstowych i daty. Robiłem to za pomocą kreatora: Project -> Add Class... -> MFC -> MFC ODBC Consumer. W kreatorze trzeba bylo wskazać źródło danych ODBC (takie samo okienko jak w Panel Sterowania -> Narzędzia Administarcyjne -> Źródła danych (ODBC)). Utworzona została klasa, dziedzicząca z klasy CRecordset, która posiadała pola i nazwę takie jak tabela w bazie danych.

	long	m_ID; // w pliku .h klasy dziedziczącej z CRecordset
	CStringW	m_Imie;
	CStringW	m_Nazwisko;
	CStringW	m_Miejscowosc;
	CTime	m_Data_dodania;
	CTime	m_Data_rozpoznania;
	BYTE	m_Palec;
COsoby::COsoby(CDatabase* pdb) // w pliku .cpp klasy dziedziczącej z CRecordset
	: CRecordset(pdb)
{
	m_ID = 0;
	m_Imie = L"";
	m_Nazwisko = L"";
	m_Miejscowosc = L"";
	m_Data_dodania;
	m_Data_rozpoznania;
	m_Palec = 0;
	m_Obraz;
	m_nFields = 7;
	m_nDefaultType = dynaset;
}
void COsoby::DoFieldExchange(CFieldExchange* pFX) // w pliku .cpp klasy dziedziczącej z CRecordset
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_Long(pFX, _T("[ID]"), m_ID);
	RFX_Text(pFX, _T("[Imie]"), m_Imie);
	RFX_Text(pFX, _T("[Nazwisko]"), m_Nazwisko);
	RFX_Text(pFX, _T("[Miejscowosc]"), m_Miejscowosc);
	RFX_Date(pFX, _T("[Data_dodania]"), m_Data_dodania);
	RFX_Date(pFX, _T("[Data_rozpoznania]"), m_Data_rozpoznania);
	RFX_Byte(pFX, _T("[Palec]"), m_Palec);

}

Wszystko działało jak należy - program się łączył i pobierał wszystkie dane oraz mógł na tabeli w bazie operować. Jendak, gdy chiałem program poszerzyć o obsługę wczytywania i zapisywania obrazu do bazy, zaczął pojawiać się błąd w momecie jego uruchamiania:

Nieprawidłowy indeks deskryptora

Wygląd nowej klasy jest bardzo podobny, z ty, ze pojawiły się wpisy dotyczące pola image:

	CLongBinary	m_Obraz; // w pliku .h klasy dziedziczącej z CRecordset
[...]
	m_Obraz; //w pliku .cpp klasy dziedziczącej z CRecordset
	m_nFields = 8;
[...]
	RFX_LongBinary(pFX, _T("[Obraz]"), m_Obraz); 

Program kompiluje się bezbłędnie, jednak nie da się go uruchomić. Literówka nie jest możliwa, ponieważ tę klase kompilator tworzy sam, na podstawie Tabeli w bazie danych. Co więcej, gdy odkomentuję te pola, a m_nFields zmienię na 7, wszystko znów działa. Komunikat z błędem pojawia się

Komunikat z błędem pojawia się, gdy tworzony jest obiekt klasy, która dziedziczy z CRecordset. Chyba w miejscu RFX_LongBinary(pFX, _T("[Obraz]"), m_Obraz);. Próbowałem bawić się z typami, okazało się, że wszystkie typy jakie mam do dyspozycji to:

/////////////////////////////////////////////////////////////////////////////
// Standard Recordset Field Exchange routines

// text data
void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName, CStringW &value,
	// Default max length for char and varchar, default datasource type
	int nMaxLength = 255, int nColumnType = SQL_VARCHAR, short nScale = 0);
void AFXAPI RFX_Text(CFieldExchange* pFX, LPCTSTR szName, CStringA &value,
	// Default max length for char and varchar, default datasource type
	int nMaxLength = 255, int nColumnType = SQL_VARCHAR, short nScale = 0);

void AFXAPI RFX_Text(__in CFieldExchange* pFX, __in_z LPCTSTR szName, __out_ecount(nMaxLength) __out_z LPWSTR value,
	__in int nMaxLength, __in int nColumnType = SQL_VARCHAR, __in short nScale = 0);
void AFXAPI RFX_Text(__in CFieldExchange* pFX, __in LPCTSTR szName, __out_ecount(nMaxLength) __out_z LPSTR value,
	__in int nMaxLength, __in int nColumnType = SQL_VARCHAR, __in short nScale = 0);

// boolean data
void AFXAPI RFX_Bool(CFieldExchange* pFX, LPCTSTR szName, BOOL& value);

// integer data
void AFXAPI RFX_Long(CFieldExchange* pFX, LPCTSTR szName, long& value);
void AFXAPI RFX_Int(CFieldExchange* pFX, LPCTSTR szName, int& value);
void AFXAPI RFX_Single(CFieldExchange* pFX, LPCTSTR szName, float& value);
void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName, double& value);
void AFXAPI RFX_BigInt(CFieldExchange* pFX, LPCTSTR szName, LONGLONG& value);

// date and time
void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, CTime& value);
void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, TIMESTAMP_STRUCT& value);
void AFXAPI RFX_Date(CFieldExchange* pFX, LPCTSTR szName, COleDateTime& value);

// Binary data
void AFXAPI RFX_Binary(CFieldExchange* pFX, LPCTSTR szName, CByteArray& value,
	// Default max length is for binary and varbinary
	INT_PTR nMaxLength = 255);
void AFXAPI RFX_Byte(CFieldExchange* pFX, LPCTSTR szName, BYTE& value);
void AFXAPI RFX_LongBinary(CFieldExchange* pFX, LPCTSTR szName, CLongBinary& value);

/////////////////////////////////////////////////////////////////////////////

Dla jasności powiem, że uzywam VC++ w wersji 8 (2005), używam klas MFC, system Widnows XP.

Proszę o pomoc i cierpliwość :)

0

Ciekawe, bo kiedy metoda DoFieldExchange() wygląda tak:

void COsoby::DoFieldExchange(CFieldExchange* pFX)
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_Long(pFX, _T("[ID]"), m_ID);
	RFX_Text(pFX, _T("[Imie]"), m_Imie);
	RFX_Text(pFX, _T("[Nazwisko]"), m_Nazwisko);
	RFX_Text(pFX, _T("[Miejscowosc]"), m_Miejscowosc);
	RFX_Date(pFX, _T("[Data_dodania]"), m_Data_dodania);
	RFX_Date(pFX, _T("[Data_rozpoznania]"), m_Data_rozpoznania);
	RFX_Byte(pFX, _T("[Palec]"), m_Palec);
	RFX_LongBinary(pFX, _T("[Obraz]"), m_Obraz);
}

Wyskauje błąd Nieprawidłowy indeks deskryptora. Natomiast gdy ostatnia pozycja jest w każdym innym miejscu, np:

void COsoby::DoFieldExchange(CFieldExchange* pFX)
{
	pFX->SetFieldType(CFieldExchange::outputColumn);
	RFX_LongBinary(pFX, _T("[Obraz]"), m_Obraz);
	RFX_Long(pFX, _T("[ID]"), m_ID);
	RFX_Text(pFX, _T("[Imie]"), m_Imie);
	RFX_Text(pFX, _T("[Nazwisko]"), m_Nazwisko);
	RFX_Text(pFX, _T("[Miejscowosc]"), m_Miejscowosc);
	RFX_Date(pFX, _T("[Data_dodania]"), m_Data_dodania);
	RFX_Date(pFX, _T("[Data_rozpoznania]"), m_Data_rozpoznania);
	RFX_Byte(pFX, _T("[Palec]"), m_Palec);
}

pojawia się błąd następującej treści: Naruszenie atrybutu ograniczonego typu danych. Wyglada jak, by coś było z tym typem. Ciekawe jest to, iż wygląda, jakby funkcja DoFieldExchange() wykonywała się dwukrotnie (kiedy ustawię debugowanie z breakpointem). Debuger zatrzymuje sie we wskazanym miejscu dwa razy. Pierwszy raz, wygląda jak by wszystko było OK, a drugim razem pFX podświetla się na czerwono. Po minięciu tego miejsca, generowany jest błąd, o którym mowa.</quote>

0

Przytoczę wartości pFX przy pierwszym i przy drugim wywołaniu (samoczynnym) funkcji DoFieldExchange()

-		pFX	0x0012f3fc {m_nOperation=2 m_prs=0x007bf028 m_nFieldType=4294967295 ...}	CFieldExchange *
		m_nOperation	2	unsigned int
+		m_prs	0x007bf028 class COsoby osoby {COsoby}	CRecordset *
		m_nFieldType	4294967295	unsigned int
		m_nFieldFound	8122408	unsigned int
+		m_pstr	0x00000000	ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t> > > *
		m_bField	0	int
		m_pvField	0x00000000	void *
+		m_lpszSeparator	0x003f80f8 "????????"	const wchar_t *
		m_nFields	0	unsigned int
		m_nParams	0	unsigned int
		m_nParamFields	0	unsigned int
		m_hstmt	0x00cc1cb8	void *
		m_lDefaultLBFetchSize	65536	long
		m_lDefaultLBReallocSize	65536	long
+		m_pdcDump	0x0012f44c {m_nDepth=8122408 m_pFile=0x0012f4c0 }	CDumpContext *
-		pFX	0x0012f3fc {m_nOperation=14 m_prs=0x007bf028 m_nFieldType=4294967295 ...}	CFieldExchange *
		m_nOperation	14	unsigned int
+		m_prs	0x007bf028 class COsoby osoby {COsoby}	CRecordset *
		m_nFieldType	4294967295	unsigned int
		m_nFieldFound	8122408	unsigned int
+		m_pstr	0x00000000	ATL::CStringT<wchar_t,StrTraitMFC<wchar_t,ATL::ChTraitsCRT<wchar_t> > > *
		m_bField	0	int
		m_pvField	0x00000000	void *
+		m_lpszSeparator	0x003f80f8 "????????"	const wchar_t *
		m_nFields	0	unsigned int
		m_nParams	0	unsigned int
		m_nParamFields	0	unsigned int
		m_hstmt	0x00000000	void *                     <- ZAZNACZONE NA CZERWONO
		m_lDefaultLBFetchSize	65536	long
		m_lDefaultLBReallocSize	65536	long
+		m_pdcDump	0x0012f44c {m_nDepth=8122408 m_pFile=0x0012f4c0 }	CDumpContext *

Być może nie ma to znaczenia. Już na prawdę nie wiem, czego mógłbym się czepić. Wszystkie przykłady, jakie znalazłem, tak właśnie działały. Bo i czemu miały by nie działać, skoro ciało funkcji, ba cała klasa generowana jest automatycznie! Help please...

1 użytkowników online, w tym zalogowanych: 0, gości: 1