Page 1 of 1
OleDb and MS Access
Posted: 29.05.2023, 09:58
by abonic
The OleDb protocol does not support writing of BIT(Boolean) and DATETIME fields to the MS Access MDB from dataset controls. The problem with the DATETIME field can be solved by adding the following line to the code:
Code: Select all
ZConnection1.Properties.Add('DatetimeWriteFormat=YYYY-MM-DD HH:NN:SS');
Is there something similar for a BIT data type or any other way to allow that field to be written to the database?
Tested with trunk svn 8005, as it is the last version that can be compiled with Delphi 2009. By the way, apart from the above, I don't see any other problems in working with the MS Access database.
Re: OleDb and MS Access BIT(Boolean) data type
Posted: 30.05.2023, 12:26
by abonic
Correction: BIT fields work correctly. I mistakenly used one of the reserved words as a field name in the test.
On the other hand, I don't know why this is a problem given that the 'IdentifierQuoteString' value is correctly set to '[]'.
EDIT: Of all the reserved words, I hit exactly one that is not in the list returned by GetIdentifierQuoteKeywordsSorted - 'Logical'.
Re: OleDb and MS Access
Posted: 31.05.2023, 11:06
by abonic
After additional testing, a new problem: it is not possible to write negative values in SHORT and LONG integer fields.
For example, if I try to write -5 in the SHORT field, the parameter that ZEOS will pass is '-'. The last character seems to have been cut off.
ZSQLMonitor1LogTrace:
... cat: Prepare, proto: OleDB, msg: Statement 4 : INSERT INTO T1 (ID,fShort) VALUES (?,?)
... cat: Bind prepared, proto: OleDB, msg: Statement 4 :
'2','-'
... cat: Execute prepared, proto: oledb, msg: Statement 4 : INSERT INTO T1 (ID,fShort) VALUES (?,?), errcode: -198708185, error: OLEDB Error
SQLState: 3060 Native Error: -198708185
Error message: Wrong data type for parameter ''.
Source: Microsoft JET Database Engine
oledb mdb.rar
Re: OleDb and MS Access
Posted: 31.05.2023, 14:16
by miab3
Yes indeed. This error occurs for OleDB. Auto_increment doesn't work either.
In the analogous connection via ADO everything works.
Michal
Re: OleDb and MS Access
Posted: 31.05.2023, 16:11
by abonic
With ADO everything works, but it would be nice to have the performance improvement offered by OleDB.
OleDB ado
table open 0.025 0.648
table scan 0.889 4.012
sql select 0.866 1.183
sql insert 1.523 2.321
Re: OleDb and MS Access
Posted: 31.05.2023, 16:25
by miab3
Yes, I wrote some time ago that ADO is the slowest option.
It is possible that in the case of Access OleDB is defective in detecting field types
Michał
Re: OleDb and MS Access
Posted: 31.05.2023, 19:44
by abonic
I think I found a solution to the bug with negative integer values.
Code: Select all
unit ZDbcOleDBStatement;
...
procedure TZOleDBPreparedStatement.InternalBindSInt(Index: Integer;
SQLType: TZSQLType; Value: NativeInt);
...
// PDBLENGTH(PAnsiChar(fDBParams.pData)+Bind.obLength)^ := L shl 1 + Byte(Ord(Negative)); // length of '-5' is 3 here
PDBLENGTH(PAnsiChar(fDBParams.pData)+Bind.obLength)^ := (L + Byte(Ord(Negative))) shl 1; // should be 4
I'm not sure if this change breaks something in other databases, but it works without problems with access mdb, at least judging by the attached test application.
... cat: Prepare, proto: OleDB, msg: Statement 4 : INSERT INTO T1 (ID,fShort) VALUES (?,?)
... cat: Bind prepared, proto: OleDB, msg: Statement 4 :
'2','-5'
... cat: Execute prepared, proto: OleDB, msg: Statement 4, elapsed time: '00:00:00.000'
Re: OleDb and MS Access
Posted: 01.06.2023, 09:25
by miab3
The error of negative values disappeared in my test too.
The same sequence is present in 'ZDbcOleDBStatement.pas' in one more place.
Unfortunately, autonumber for Access still doesn't work.
Michał
Re: OleDb and MS Access
Posted: 01.06.2023, 09:52
by marsupilami
Hello abonic,
I applied the patch. Thank you for contributing
Best regards,
Jan
Re: OleDb and MS Access
Posted: 01.06.2023, 10:17
by abonic
miab3 wrote: ↑01.06.2023, 09:25
The same sequence is present in 'ZDbcOleDBStatement.pas' in one more place.
I guess that line should be corrected in the same way. The problem is that I cannot create a situation where that part of the code would be executed.
Unfortunately, autonumber for Access still doesn't work.
The problem with the AutoIncrement field is here. Flags does not contain information about AutoIncrement for the mdb database.
Code: Select all
function TOleDBDatabaseMetadata.UncachedGetColumns
...
Result.UpdateBoolean(TableColColumnAutoIncIndex, Flags and DBCOLUMNFLAGS_ISROWID = DBCOLUMNFLAGS_ISROWID);