15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


ODBC ASSERT question...

David Little -- dlittle@equinoxcorp.com
Friday, January 24, 1997

Environment: VC4.2b/Win95

I have an application using ODBC and the Access7.0 drivers, and I have
been getting an ASSERTion in DBRFX.CPP line 271:

			if (pInfo->m_pvBindAddress != pvBind)
			{
				TRACE1("Error: field address (column %u) has changed!\n",
					nField);
				ASSERT(FALSE);
			}

It happens if I try an Edit(), then something like this: deptTable->m_Total_Today.Format("%.4f", newTotal);
and will go away if I change it to this:
	CString t;
            t.Format("%.4f", newTotal);
            deptTable->m_Total_Today = t;

Does anybody know why this might happen, and the impact on the database?  

Thanks!

David


            //deptTable->m_Total_Today = t;




Vincent Mascart -- 100425.1337@compuserve.com
Sunday, January 26, 1997

[Mini-digest: 2 responses]

>From: 	David Little
>Sent: 	dimanche 26 janvier 1997 19:10
>To: 	"'MFC Question'"
>Subject: 	ODBC ASSERT question...
>
>Environment: VC4.2b/Win95
>
>I have an application using ODBC and the Access7.0 drivers, and I have
>been getting an ASSERTion in DBRFX.CPP line 271:
>
>			if (pInfo->m_pvBindAddress != pvBind)
>			{
>				TRACE1("Error: field address (column %u) has
changed!\n",
>					nField);
>				ASSERT(FALSE);
>			}
>
>It happens if I try an Edit(), then something like this:
deptTable->m_Total_Today.Format("%.4f", >newTotal);
>and will go away if I change it to this:
>	CString t;
>            t.Format("%.4f", newTotal);
>            deptTable->m_Total_Today = t;
>
>Does anybody know why this might happen, and the impact on the database?  
>
>Thanks!

Hi David,

This is because buffer bound to field in database must not move. When you make a
Format() with a CString, MFC allocate a new buffer large enough to contain the
expected result of the operation. This will cause the string buffer to move if
the estimated result buffer length is greater than the field length.

That why you don't assert with the deptTable->m_Total_Today = t; version. The
size of the preallocated buffer for deptTable->m_Total_Today is large enough to
contain the content of your t CString.

HTH

Vincent Mascart
100425.1337@compuserve.com

-----From: Mike Blaszczak 

At 12:26 1/24/97 -0600, David Little wrote:
>Environment: VC4.2b/Win95

>I have an application using ODBC and the Access7.0 drivers, and I have
>been getting an ASSERTion in DBRFX.CPP line 271:
>
>if (pInfo->m_pvBindAddress != pvBind)
>{
>	TRACE1("Error: field address (column %u) has changed!\n",
>		nField);
>	ASSERT(FALSE);
>}

The message means exactly what it says: you've changed the address of one of
the items you previously bound to a database column.

Binding output buffers to a database column means that you've told you want
data from a given column to show up at a given address.  When you access the
database, you first declare your intent to execute a SQL Statement.  You
provide that statement to the database API, and it parses it.  If it
successfully parses, the database API knows how many (if any) columns the
query will return.

You then start telling the database API that, each time you retrieve a row
from the result set of the query, you want a given column's data to appear
at a particular place in memory.  When you move to the first record, the
database API copies information for each column that you've bound to the
address that you said you've bound it to.  When you move to the next record,
the API tries to use the same addresses.

When you use ODBC (or SQL Server's DB-Library, or Gupta's SQLAPI, or 
Oracle's Pro*C API), you can't change the address you've bound to after
you've bound it.  If you need to change the address, you need to reexecute
the query.

Since MFC notices that you changed the address, it stops you in your tracks
and issues a TRACE that explains what happened.

>It happens if I try an Edit(), then something like this:
>	deptTable->m_Total_Today.Format("%.4f", newTotal);

Presumably, m_Total_Today is a CString.  When you use Format() directly
on the CString, the string data ends up being destroyed and reallocated
and that effectively moves the address of the buffer.

>and will go away if I change it to this:
>	CString t;
>            t.Format("%.4f", newTotal);
>            deptTable->m_Total_Today = t;

CString includes optimizations that prevent the buffer from (usually)
moving in this case.

>Does anybody know why this might happen, and the impact on the database?  

There's no impact on the database: you've raised an error, the transaction
is rolled back, and that's that.  The reason that most database APIs
don't allow switching around bound addresses is for performance.


.B ekiM
http://www.nwlink.com/~mikeblas/
Why does the "new" Corvette look like a 1993 RX-7?
These words are my own. I do not speak on behalf of Microsoft.





| Вернуться в корень Архива |