HI zusammen,
ich habe ein großes Problem mit dem ODBC Treiber von PostgreSQL, aber erst mal eine Kurze Beschreibung worum es geht:
Ich portiere zur Zeit eine Anwendung, die mit Gupta-SQL-Windows programmiert ist (4GL Sprache vergleichbar mit Delphi), WindowsXP von der eigenen Gupta-SQL-Base auf PostgreSQL 8.2.
Auf die Datenbank greife ich über ODBC zu (Version 8.02.02.00 Unicode, Datenbank ist UTF8 codiert). So weit so gut.
Da ich ziemlich umfangreiche Transaktionen habe, arbeite ich (natürlich) ohne Autocommit und bin dabei auf folgendes Verhalten gestoßen:
Zum Beispiel werden Datensätze in eine Tabelle eingefügt und dann wieder ausgelesen. Da alles innerhalb einer Transaktion läuft sollte man meinen, dass man die Datensätze sieht, die da eben eingefügt wurden.
Der Code mit dem das passiert könnte so aussehen:
Set sUser = ‘SYSADM’
Set sWS = ‘WS_JSP’
!
Set sInfo = ‘Test1’
Set nError = nError and SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ’ )
!
Set sInfo = ‘Test2’
Call SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ’ )
!
Set sInfo = ‘Test3’
Call SqlPrepareAndExecute( hSql, 'insert into sysadm.log (dbuser, ws, info) Values ( :sUser, :sWS, :sInfo ) ’ )
!
Set sInfo = ‘’
!
Call SqlPrepareAndExecute( hSql, ‘Select info from sysadm.log into :sInfo’ )
Call SqlFetchNext( hSql, nError )
Call SQLCommit(hSql)
sUser, sWS und sInfo sind lokale String Variablen, hSql ist ein SQL-Handle oder eine Connection
(Es handelt sich hier natürlich nicht um den echten Code, sondern nur um ein Beispiel, das ganze Fehlerhandling fehlt hier)
Wenn ich vor dem Select ein Commit mache geht alles wunderbar. Wenn ich den Commit dort mache, wo er jetzt steht wird nichts selektiert und die Datensätze kommen auch nicht in der Tabelle an.
Wenn man sich jetzt das Logfile des ODBC-Treibers ansieht erkennt man auch sofort warum:
conn=01ED9A78, PGAPI_DriverConnect( in)='DSN=ALSAPLOG;UID=sysadm;PWD=xxxxxxxx;DATABASE=alsaplog;SERVER=localhost;PORT=5432;CA=d;A6=;A7=100;A8=4096;B0=254;B1=32000;BI=0;C2=dd;CX=1bd27bb;A1=7.4-1;’, fDriverCompletion=0
DSN info: DSN=‘ALSAPLOG’,server=‘localhost’,port=‘5432’,dbase=‘alsaplog’,user=‘sysadm’,passwd=‘xxxxx’
onlyread=‘0’,protocol=‘7.4’,showoid=‘0’,fakeoidindex=‘0’,showsystable=‘0’
conn_settings=’’,conn_encoding=‘OTHER’
translation_dll=’’,translation_option=’’
Global Options: Version=‘08.02.0200’, fetch=100, socket=4096, unknown_sizes=0, max_varchar_size=254, max_longvarchar_size=32000
disable_optimizer=1, ksqo=1, unique_index=1, use_declarefetch=0
text_as_longvarchar=1, unknowns_as_longvarchar=0, bools_as_char=1 NAMEDATALEN=64
extra_systable_prefixes=‘dd_’, conn_settings=’’ conn_encoding=‘OTHER’
[ PostgreSQL version string = ‘8.2.1’ ]
[ PostgreSQL version number = ‘8.2’ ]
conn=01ED9A78, query=‘select oid, typbasetype from pg_type where typname = ‘lo’’
[ fetched 0 rows ]
[ Large Object oid = -999 ]
[ Client encoding = ‘UTF8’ (code = 6) ]
conn=01ED9A78, PGAPI_DriverConnect(out)=’(NULL)’
CONN ERROR: func=SQLDriverConnectW, desc=’’, errnum=215, errmsg=‘the ConnStrOut is too small’
henv=01ED3E10, conn=01ED9A78, status=1, num_stmts=16
sock=01EDE8B0, stmts=01ED8C80, lobj_type=-999
---------------- Socket Info -------------------------------
socket=1536, reverse=0, errornumber=0, errormsg=’(NULL)’
buffer_in=32359872, buffer_out=32370328
buffer_filled_in=77, buffer_filled_out=0, buffer_read_in=77
conn=01ED9A78, query=‘show max_identifier_length’
[ fetched 1 rows ]
conn=01ED9A78, query=‘insert into sysadm.log (dbuser, ws, info) Values ( E’SYSADM’ , E’WS_JSP’ , E’Test1’ ) ’
conn=01ED9A78, query=‘insert into sysadm.log (dbuser, ws, info) Values ( E’SYSADM’ , E’WS_JSP’ , E’Test2’ ) ’
conn=01ED9A78, query=‘insert into sysadm.log (dbuser, ws, info) Values ( E’SYSADM’ , E’WS_JSP’ , E’Test3’ ) ’
conn=01ED9A78, query='Select info from sysadm.log ’
[ fetched 3 rows ]
conn=01ED9A78, query=‘select n.nspname, c.relname, a.attname, a.atttypid, t.typname, a.attnum, a.attlen, a.atttypmod, a.attnotnull, c.relhasrules, c.relkind, c.oid, d.adsrc from (((pg_catalog.pg_class c inner join pg_catalog.pg_namespace n on n.oid = c.relnamespace and c.oid = 54883) inner join pg_catalog.pg_attribute a on (not a.attisdropped) and a.attnum > 0 and a.attrelid = c.oid) inner join pg_catalog.pg_type t on t.oid = a.atttypid) left outer join pg_attrdef d on a.atthasdef and d.adrelid = a.attrelid and d.adnum = a.attnum order by n.nspname, c.relname, attnum’
[ fetched 12 rows ]
PGAPI_Columns: table=‘log’,field_name=‘zeit’,type=1114,name=‘timestamp’
PGAPI_Columns: table=‘log’,field_name=‘dbuser’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘ws’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘modul’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘info’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘fenster’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘salcomtype’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘iserror’,type=21,name=‘int2’
PGAPI_Columns: table=‘log’,field_name=‘errnumber’,type=23,name=‘int4’
PGAPI_Columns: table=‘log’,field_name=‘statement’,type=25,name=‘text’
PGAPI_Columns: table=‘log’,field_name=‘comtyp’,type=1043,name=‘varchar’
PGAPI_Columns: table=‘log’,field_name=‘dbtable’,type=1043,name=‘varchar’
conn=01ED9A78, query='ROLLBACK’
conn=01ED9A78, query='Select info from sysadm.log ’
[ fetched 0 rows ]
conn=01ED9A78, query=‘COMMIT’
conn=01ED9A78, PGAPI_Disconnect_
Hier sieht man in der unteren Hälfte sehr deutlich die Inserts und dann den Select. Dann folgen Befehle, mit denen das Laufzeitsystem ermittelt, welche Spalten die Tabelle hat, auf der der Select läuft, und dann ein ROLLBACK. Mitten in der Transaktion. Und dann sind die eingefügten Zeilen natürlich wieder weg.
Der erste Select ist also nur ein Dummy-Select, um die Struktur des Ergebnisses zu erfahren, dann kommt der Rollback und dann erfolgt der eigentliche Select, um die Daten zu holen, die dann natürlich weg sind.
In der Log-Datei, die die Gupta schreibt fehlt dieses Rollback und auch mit SQL-Server ODBC funktioniert es einwandfrei. Deswegen habe ich den PG-ODBC Treiber in Verdacht. Habe ich hier evtl nur die falschen Einstellungen ? oder hat da sonst jemand eine Idee was ich falsch mache.
Aber grundsätzlich muss es doch möglich sein innerhalb einer Transaktion Daten zu schreiben und dann evtl. auch ganz andere zu lesen. Das kann doch nicht sein, dass da noch ein Fehler an dieser Stelle im Treiber ist.
Der ODBC Treiber ist mit folgenden Einstellungen installiert.
Datasource/Page1
Disable Genetic Optimizer = ON
KSQO = ON
Recognize Unique Indexes = ON
Use Declare/Fetch = OFF
CommLog = ON (zum testen, sonst OFF)
Parse Statements = OFF
Cancel as FreeStmt = OFF (testweise ON, bringt aber auch nichts)
MyLog = OFF
Unknown Size = Maximum
Data Type Options
Test as LongVarChar = ON
Unknowns as LongVarChar = OFF
Bools as Char = ON
Miscellaneous
Max Varchar = 254
Max Long Varchar = 32000
Chache Size = 100
Sys Table Prefix = dd_:
Datasource/Page2
Read Only = OFF
Show System Table = OFF
LF <-> CR/LF conversion = ON
Updateable Cursors = ON
bytea as LO = OFF
Row Versioning = ON
Disallow Premature = OFF
True is -1 = OFF
Server side prepare = OFF
INT9 as = Default
Protokoll = 7.4+
Level of rollback on errors = Transaction
OID Opitions = OFF
Treiber PostgreSQL Unicode
Für Hilfe wäre ich sehr dankbar, sonst kann ich das Projekt abschreiben.
JSP