Domino 9 und frühere Versionen > ND6: Entwicklung
Probleme beim Schreiben von Daten über ODBC in SQL Server
PeterD2:
Ich habe einige Agenten, die bisher nachts automatisch einige Statistikdaten aus Notes über eine ODBC Verbindung in eine MySQL Datenbank geschrieben haben. Jetzt wurde die Datenbank auf MS SQL Server migirert und nichts geht mehr :-\
Ich habe die entsprechende System DSN auf dem Domino Server neu eingerichtet, so dass jetzt unter gleichem Namen und mit den gleichen Credentials anstelle der MySQL Datenbank der MS SQL Server erreicht werden kann. Ein Verbindungstest im Assistenten zur Einrichtung der ODBC System DSN ist erfolgreich. Die richtige Vorgabedatenbank ist in den Einstellungen der ODBC Verbindung gesetzt.
Ich habe mir jetzt folgenden kleinen Agenten geschrieben, der die Arbeit mit der neuen Datenbank testen soll:
--- Code: ---
Sub Initialize
Dim ExportProfileDoc As NotesDocument
Dim session As New NotesSession
Dim dbCurr As NotesDatabase
Dim con As New ODBCConnection
Dim dsn As String
Dim user As String
Dim passwd As String
Dim qry As ODBCQuery
Dim result As ODBCResultSet
Set dbCurr=session.CurrentDatabase
Set ExportProfileDoc = dbCurr.GetProfileDocument("PROFILE XMLExport")
dsn = GetFieldValueTxt( ExportProfileDoc,"LeadExportSystemDSN")
user =GetFieldValueTxt( ExportProfileDoc,"LeadExportSystemDsnUser")
passwd = GetFieldValueTxt( ExportProfileDoc,"LeadExportSystemDsnPassword")
Set con = New ODBCConnection
Set qry = New ODBCQuery
Set result = New ODBCResultSet
Set qry.Connection = con
Set result.Query = qry
con.ConnectTo(dsn)
qry.SQL = "SELECT * FROM ADDRESSRECORDS"
If Not result.Execute Then
Messagebox result.GetExtendedErrorMessage,,result.GetErrorMessage
Exit Sub
End If
'If Not con.ConnectTo(dsn,user,passwd) Then
' Messagebox "Could not connect to " & dsn,, "Error"
' Exit Sub
'End If
'qry.SQL = "Select * from leadrecords"
'Set qry.Connection = con
'Set result.Query = qry
'result.Execute
'erst einmal Lesen üben
Dim i As Integer
result.LastRow
i = result.NumRows
result.addRow
Call result.SetValue("doctype","Provisionsabrechnung")
Call result.SetValue("lead_type","A")
Call result.SetValue("cust_salutation","Herr")
Call result.SetValue("cust_title","Dr.")
Call result.SetValue("cust_firstname","Walter")
Call result.SetValue("cust_lastname","Milchmann")
Call result.SetValue("cust_street","Am Milchberg")
Call result.SetValue("cust_streetnr","2b")
Call result.SetValue("cust_town","Dumpfhausen")
Call result.SetValue("cust_zip","34257")
Call result.SetValue("cust_phone1","5657/85858")
Call result.SetValue("cust_email","zappado@gmx.de")
Call result.SetValue("estate_type","Einfamilienhaus")
Call result.SetValue("estate_usage","")
Dim status As Variant
Dim ro As Variant
status = result.UpdateRow
ro = result.ReadOnly
result.Close(DB_CLOSE)
con.Disconnect
Print "Fertig"
End Sub
--- Ende Code ---
Bei dem momentan auskommentierten Teil erfolgt die Anmeldung vollautomatisch, bei der jetzt genutzten Methode muss ich das Passwort manuell eingeben. Die abgefragte Tabelle enthält ca. 200.000 Datensätze.
Was passiert nun bei der Ausführung des Codes:
- Ich werde zur Eingabe des Passworts aufgefordert
- Die Prüfung
--- Code: ---If Not result.Execute Then
--- Ende Code ---
ist erfolgreich, d.h. es erscheint keine Messagebox
-
--- Code: ---i = result.NumRows
--- Ende Code ---
liefert -1
-
--- Code: ---status = result.UpdateRow
--- Ende Code ---
liefert false
-
--- Code: ---ro = result.ReadOnly
--- Ende Code ---
liefert ebenfalls false
Und nun stehe ich auf dem Schlauch. Obwohl zuerst offensichtlich erfolgreich eine ODBCConnection zur Datenbank aufgebaut wird, kann die Anzahl der Zeilen im result nicht ermittelt werden, und obwohl die Datenbank nicht readOnly ist, kann ich keine Datensätze hineinschreiben. Natürlich kann ich auch aus den Logs des SQL Servers nichts sehen. Dort erscheint noch nicht einmal ein Eintrag für den Versuch des Anmeldens durch meinen Benutzer.
Ich habe jetzt gar keinen Anhaltspunkt wie ich noch testen kann woran das Problem liegt. Hat jemand einen Vorschlag?
Danke im Voraus
Peter
ZaLudtske:
Gibt es im ODBC-Treiber eine Option für Lese- bzw. Schreib-Zugriff?
Wenn Ja, sind diese korrekt eingestellt?
rainer
PeterD2:
Nein, solche Optionen gibt es nicht. Außerdem funktioniert offensichtlich weder das Lesen noch das Schreiben, da ja dei Anzahl der Zeilen des ODBCResultset auch nicht richtig ermittelt wird.
m3:
IMHO liegt das Problem im Verbindungsaufbau.
Du hast schon ein "Dim con As New ODBCConnection" da ist das "Set con = New ODBCConnection" unnötig.
Weiter gehts dann mit
--- Code: --- Set qry = New ODBCQuery
Set result = New ODBCResultSet
Set qry.Connection = con
--- Ende Code ---
Wieso weist du der ODBCQuery schon die Connection zu, obwohl Du diese noch nicht mal aufgemacht hast?
--- Code: ---con.ConnectTo(dsn)
qry.SQL = "SELECT * FROM ADDRESSRECORDS"
--- Ende Code ---
Du machst ein connect, überprüfst nicht, ob das gut gegangen ist und wunderst Dich dann später, dass die Abfragen nicht funktionieren?
Hüstel.
Die Designer-Hilfe mein (leicht abgewandelt) dazu:
--- Code: --- If Not con.IsConnected
....
End If
--- Ende Code ---
PeterD2:
--- Zitat ---Wieso weist du der ODBCQuery schon die Connection zu, obwohl Du diese noch nicht mal aufgemacht hast?
--- Ende Zitat ---
..weil ich das für diesen Testagenten genau so aus der Notes Designer Hilfe entnommen habe, eben genau um mich da in der Reihenfolge garantiert nicht zu vertun. Siehe Stichwort: "Examples: Execute Method"
--- Zitat ---Du machst ein connect, überprüfst nicht, ob das gut gegangen ist und wunderst Dich dann später, dass die Abfragen nicht funktionieren?
Hüstel.
--- Ende Zitat ---
Auch das ist dem Testagenten geschuldet, in dem ich stattdessen prüfe ob das Execute Statement erfolgreich war. Mein "echter" Agent enthält sehr wohl eine Prüfung, aber das bringt mich nicht weiter:
--- Code: ---If Not con.ConnectTo(dsn,user,passwd) Then
Messagebox "Could not connect to " & dsn,, "Error"
Exit Sub
End If
--- Ende Code ---
Ich habe mittlerweile noch etwas herumgespielt, und vielleicht einen Hinweis gefunden. Ich habe folgende kleine Ergänzung vorgenommen:
--- Code: ---
Set con = New ODBCConnection
con.SilentMode = True
Set qry = New ODBCQuery
Set result = New ODBCResultSet
Set qry.Connection = con
Set result.Query = qry
status= con.ConnectTo(dsn,user,passwd)
'status= con.ConnectTo(dsn)
'Es gibt zwei alternative Anmeldekommandos, je nachem ob ich die System DSN mit Windows Authentifizierung oder SQl Server Authentifizierung teste
qry.SQL = "SELECT * FROM LEADRECORDS"
If Not result.Execute Then
Messagebox result.GetExtendedErrorMessage,,result.GetErrorMessage
Exit Sub
End If
tables = con.ListTables(dsn)
If con.GetError <> DBstsSuccess Then
Messagebox con.GetExtendedErrorMessage,, con.GetErrorMessage
Exit Sub
End If
--- Ende Code ---
Ich setze also den silentMode der Connection auf "true" und öffne danach die Connection. (status = true danach).
Aber bei Aufruf der Zeile
--- Code: ---tables = con.ListTables(dsn)
--- Ende Code ---
werde ich plötzlich mit einem Anmeldedialog für die Datenbank konfrontiert, obwohl die Connection längst geöffnet sein sollte, und ich wegen con.silentMode=true nicht gefragt werden sollte . "tables" enthält danach tatsächlich eine Auflistung aller Tabellen der Datenbank. Die Verbindung steht also spätestens jetzt (warum nicht schon vorher entzieht sich meiner Kenntniss, da vorher bei ...
--- Code: ---If Not result.Execute Then
Messagebox result.GetExtendedErrorMessage,,result.GetErrorMessage
Exit Sub
End If
--- Ende Code ---
... ja kein Fehler ausgegeben wird.
Nichts desdo trotz liefert
--- Code: ---status = result.UpdateRow
--- Ende Code ---
wieder false zurück, und die Datenbank wird nicht aktualisiert.
Ist vielleicht ein blöder Gedanke, aber für mich sieht das so aus, als ob die Connection immer nur für das genau nächste Datenbankkommando gültig ist, und danach verworfen wird.
Navigation
[0] Themen-Index
[#] Nächste Seite
Zur normalen Ansicht wechseln