Domino 9 und frühere Versionen > ND6: Entwicklung

dynamischer Export zu Access

(1/5) > >>

Anfaenger:
Hallo erstmal,

Ich hab da so ein "kleines" Problem. Ich bin gerade dabei einen Agenten zu schreiben, der meine Views aus der Datenbank in eine AccessDB schreibt.  Der eine Agent, der die Datenbank und die Tabellen anlegt funktioniert soweit ohne Probleme.
Der andere, der eigentlich die Tabellen mit den Inhalten füllen sollte, läuft auch ohne weiteres durch, nur leider vergisst er dabei fast alle Tabellen. Er schreibt leider nur in 4 von 22 Tabellen etwas rein. Und ich find einfach nicht den Grund, weshalt er dort nichts reinschreibt.
Die Tabellen in Access heißen so wie die Views in LN, nur dass die Leerzeichen herausfefiltert werden.

Ich hoffe, ihr habt da noch ein paar Tipps..

Hier der Agent

Sub Initialize
   Dim strDB As String
   Dim dbq As String
   Dim ConnectionString As String
   Dim con As New ODBCConnection
   Dim qry As New ODBCQuery
   Dim result As New ODBCResultSet
   Dim workspace As New NotesUIWorkspace
   Dim uidoc As NotesUIDocument
   Dim entry As NotesViewEntry
   Dim vwNav As NotesViewNavigator
   Dim table As String
   Dim ret As Variant
   Dim array1(0) As String
   Dim array2(0) As String
   Dim array3(0) As String
   
   array2(0)=" "
   array3(0)=""
   Set uidoc = workspace.CurrentDocument
   Set qry.Connection = con
   Set result.Query = qry
   Set session = New NotesSession
   Set db = session.CurrentDatabase
   
   strDB = Inputbox$("Enter mdb path: ","mdb path", strDB)
   dbq = "; Dbq=C:\" & strDB
   Forall DSN In con.ListDataSources
      If (Instr(1, DSN, "Access") > 0) Then ConnectionString = DSN & dbq
   End Forall
   If Not con.ConnectTo( ConnectionString ) Then
      Messagebox "Could not connect to: " & ConnectionString
      Exit Sub
   Else
      Messagebox "Connected to: " & ConnectionString
   End If
   Set qry.Connection = con   
   
   Vlist= db.views
   K=Ubound(Vlist)
   For i = 0 To K
      If Len(Vlist(i).Name) >0 Then   
         FieldName=Trim(Vlist(i).Name)                   
         Set view=db.GetView(FieldName)
         Set vwnav= view.createViewnav()
         Set entry=vwnav.GetFirstDocument
         table="SELECT * FROM " & Replace(FieldName," ","")
         qry.SQL=table   
         result.Execute
         Messagebox FieldName
         While Not(entry Is Nothing)   
            result.AddRow
            For j=0 To view.ColumnCount-1
               array1(0)=Trim(Cstr(entry.ColumnValues(j)))
               ret = Replace(array1, array2, array3)
               Call result.SetValue(Replace(view.columns(j).title, " ",""), ret(0))
                  
            Next j   
            result.UpdateRow            
            Set entry = vwnav.getnextdocument(entry)                         
         Wend
      End If
   Next i        
   
   result.Close(DB_CLOSE)
   con.Disconnect
End Sub

flaite:
Kann sein, dass der Cursor bei Result.updateRow nicht auf der richtigen Zeile steht.
Oder dass du result.UpdateRow nach jedem result.setValue machen mußt.
Sowas wie ODBCResultSet.updateRow gibt natürlich einen Wert zurück. Du könntest damit anfangen, dass du sowas mal logst.

Weiss eigentlich jemand, ob man das generierte SQL irgendwohin gelogt bekommt?
Ich könnte (in Hibernate) nicht anders mit generierten SQL arbeiten und das ist generiertes SQL:

--- Code: ---Call result.SetValue(Replace(view.columns(j).title, " ",""), ret(0))

--- Ende Code ---
Will sagen: Daraus entsteht ein SQL Befehl. Wir wissen nur nicht wie er aussieht.

Vielleicht findest du eine Möglichkeit, einfach den insert Befehl zusammenzupuzzeln?
Da du die Spalten der Tabelle und die entsprechenden Feldnamen in Notes eh schon hast?

Und könntest du vielleicht drüber nachdenken, dass man ein paar Kommentarzeilen spätestens dann in code einfügen könnte, wenn man diesen in ein öffentliches Forum postet?
Oder mal einen rationalen Grund nennen, warum du das nicht tust?

Ausserdem macht es in 99.8% der Fälle keinen Sinn die Struktur der Notes Datenbank 1 zu 1 in RDBMS zu übertragen.
Es ist schon ok, die create statements automatisch zu generieren. Nur dann sollte man die händisch ein bischen verändern, um vernünftiges RDBMS design in die Geschichte zu bekommen.

Gruß Axel


HH:
GetError, GetErrormessage und GetExtendedErrorMessage sind die entsprechenden Methoden um Fehler zu protokollieren. Bau doch einfach mal eine entsprechende Fehlerbehandlung in deinen Code ein. Die Hilfe bietet entsprechende Beispiele hierzu.

Hubert

flaite:
Der Klassiker:
oben->

--- Code: ---on error goto Fehler

--- Ende Code ---

unten:

--- Code: ---
exit sub
Fehler:
Dim strFehler as String
strFehler = |Fehler in %nameDesAgenten%.initialize | & Error$ & "(" & Cstr(Err) & ") in Zeile: " & Cstr(Erl)
exit sub

--- Ende Code ---

Ralf_M_Petter:
Hallo Anfänger!

table="SELECT * FROM " & Replace(FieldName," ","")

Diese Anweisung ist ein absoluter NO NO NO. SQL Statements dürfen nicht über Strings zusammengestopelt werden, da sie dann empfänglich werden für SQL Injections. Das heisst, jemand könnte eine View so benamsen, dass der Sinn deines SQL Statements verändert werden würde. Also immer!!! mit preparedStatements arbeiten oder das Feld wenn wie in diesem Fall notwendig das man mit String Zusammensetzung arbeitet das Feld überprüfen, ob es gültige Werte enthält.

Was an der Routine schief geht lässt sich wohl am besten im Debugger feststellen. Hast du es schon mal debugged und an welcher Stelle verhält es sich ungewöhnlich?

Grüße

Ralf

Navigation

[0] Themen-Index

[#] Nächste Seite

Zur normalen Ansicht wechseln