SQLite Format Problem

Datenbanklösungen mit AOO/LO

Moderator: Moderatoren

marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

SQLite Format Problem

Beitrag von marcel_at_work »

Hallöchen allerseits,

ich habe ein kleines Problem mit meiner SQLite-Datenbank und hoffe, ihr könnt mir darin weiterhelfen.

Über Starbasic, aus Base heraus, werden Kundendaten (falls noch nicht vorhanden) aus einer XML-Datei in eine SQLite-Tabelle übertragen.
Soweit funktioniert dies einwandfrei, außer es gibt in der XML-Datei ANSI-Kodierungen wie z.B. Umlaute. Ein "ö" habe ich dann über die Starbasic-MessageBox so als "ö" vorliegen.
Wenn noch keine Kundendaten in der DB vorhanden sind, kommt meine Abfrage damit klar und alles wird sauber in die DB übertragen (sprich: das "ö" liegt in SQLite auch wieder als "ö" vor). Beim nächsten Versuch, die Daten zu übertragen, gibt die Prozedur aber eine SQLExeption aus: "columnname is not unique" (Tabellenspalte ist als UNIQUE erstellt).

Code: Alles auswählen

oResultClients = createUnoService("com.sun.star.sdb.RowSet")
oResultClients.DataSourceName = sSystemName
oResultClients.CommandType = com.sun.star.sdb.CommandType.COMMAND
oResultClients.Command = "SELECT ID, name, type FROM clients ORDER BY ID"
oResultClients.Execute

Code: Alles auswählen

Schleife...
                                oResultClients.Command = "SELECT ID, name, type FROM clients WHERE name = '" & sClientName & "'"
				oResultClients.Execute
				
				If oResultClients.First = True Then
					'... falls JA, wird hier die Tabelle auf Übereinstimmung durchsucht
					nClientID = oResultClients.getString(1)

				'... falls NICHT, wird ein neuer Datensatz angelegt
				Else
					oResultClients.Command = "SELECT ID, name, type FROM clients ORDER BY ID"
					oResultClients.Execute
					oResultClients.Last()
					oResultClients.moveToInsertRow()
					oResultClients.updateString(2, sClientName)
					oResultClients.updateString(3, sClientType)
					oResultClients.insertRow()
					oResultClients.moveToCurrentRow()
					oResultClients.Last()
				End If
Ende...
Der Importvorgang der XML wird zeilenweise mit...

Code: Alles auswählen

Do While not eof(nFileNo)
		'zeilenweises Einlesen
		Line Input #nFileNo, sCurrentLine
...
... erreicht (der Standardprozedur aus der OpenOffice-Referenz) und die gesuchten Daten werden wie folgt aus der XML extrahiert:

Code: Alles auswählen

If sCurrentLine <>"" Then
			If Instr(sCurrentLine,"<Client Name=""") = 1 Then
				nCountClient = nCountClient + 1
				sClientName				= findPartString(sCurrentLine,"<Client Name=""",""" Type=""",1)
				sClientType				= findPartString(sCurrentLine,""" Type=""",""">",1)
...
Jemand einen Rat?

Liebe Grüße,

Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
RobertG
********
Beiträge: 2070
Registriert: Fr, 13.04.2012 19:28
Kontaktdaten:

Re: SQLite Format Problem

Beitrag von RobertG »

Hallo Marcel,

bei Problemen mit Sonderzeichen ist sicher auch das Betriebssystem und dessen Umgang damit wichtig. Eigentlich kodiert Base über UTF8. Wenn aber bereits eine Ausgabe über die Messagebox ein "ö" ergibt, dann ist da etwas faul.
Das ganze ist wohl mehr ein Basic als ein Base-Problem.
Wann liest Du denn mit der Messagebox aus? Woher zieht die Messagebox ihre Information?

Gruß

Robert
marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

Re: SQLite Format Problem

Beitrag von marcel_at_work »

Hallöchen Robert,

hier ist mal die gesamte Prozedur, die Datenbank wird aber außerhalb initialisiert.

Code: Alles auswählen

Sub XMLimport()
	Dim sCurrentLine, sFile, sText, sImportFilename As String
	Dim nFileNo, nCurrentLine, nCountClient As Integer
	
	nCountClient = 0
	nCurrentLine = 0

	'Definition des Dateinamens
	sImportFilename = sSystemPath & "toImport\Zeitkarten.xml"
	'*********************************************************************************************************************************************************
	'Auslesen des XMLbackupCount (Zählerstand der gesicherten XML-Dateien im Backup-Verzeichnis)
	oResultLog.beforeFirst()
	Do While oResultLog.Next()
		If oResultLog.getString(2) = "XMLbackupCount" Then nXMLbackupCount = oResultLog.getString(3)
	Loop
	
	'nXMLbackupCount hochzählen und Sicherungskopie der zu importierenden XML-Datei erstellen
	nXMLbackupCount = nXMLbackupCount + 1
	FileCopy(sImportFilename,sSystemPath & "backups\XML\timecard [" & Format(nXMLbackupCount,"0000") & "].xml")
	
	'aktualisierten Wert von nXMLbackupCount in die logs-Tabelle übertragen
	oResultLog.beforeFirst()
	Do While oResultLog.Next()
		If oResultLog.getString(2) = "XMLbackupCount" Then
			oResultLog.updateString(3, nXMLbackupCount)
			oResultLog.updateRow()
		End If
	Loop
	'*********************************************************************************************************************************************************
	'Ermittlung eines freien Datei-Handles
	nFileNo = Freefile 
	
	'Datei öffnen (Lesemodus)
	Open sImportFilename For Input As nFileNo
	
	'Schleifendurchlauf, bis Dateiende erreicht ist
	Do While not eof(nFileNo)
		'zeilenweises Einlesen
		Line Input #nFileNo, sCurrentLine
		
		sCurrentLine = trim(sCurrentLine) 'gibt den String ohne führende und nachfolgende Leerzeichen zurück
		nCurrentLine = nCurrentLine + 1 'Zähler für die eingelesenen Zeilen
		'*****************************************************************************************************************************************************
		'Alarmmeldungen:
		'Um Schäden an der Datenbank zu vermeiden, wird hier der Importvorgang abgebrochen, wenn...
		'... der XML-Header fehlerhaft ist
		If nCurrentLine = 1 And sCurrentLine <> "<?xml version='1.0' encoding='UTF-8' standalone='yes' ?>" Then
			MsgBox Chr(13) & "Die zu importierende Datei ist beschädigt oder in einem nicht unterstützten Format." & Chr(13) & "Um Schäden an der Datenbank zu vermeiden, wird der Importvorgang hiermit abgebrochen. " & Chr(13) & Chr(13), 16, "Achtung!"
			Exit Sub
		'... die zu importierende Datei keinen 'TimeTracker'-TAG enthält
		ElseIf nCurrentLine = 2 And sCurrentLine <> "<TimeTracker>" Then
			MsgBox Chr(13) & "Die zu importierende Datei ist beschädigt oder in einem nicht unterstützten Format." & Chr(13) & "Um Schäden an der Datenbank zu vermeiden, wird der Importvorgang hiermit abgebrochen. " & Chr(13) & Chr(13), 16, "Achtung!"
			Exit Sub
		'... die zu importierende Datei keinen 'Timecards'-TAG enthält
		ElseIf nCurrentLine = 10 And sCurrentLine <> "<Timecards>" Then
			MsgBox Chr(13) & "Bei der zu importierenden Datei handelt es sich NICHT um 'Zeitkarten.xml'. " & Chr(13) & "Um Schäden an der Datenbank zu vermeiden, wird der Importvorgang hiermit abgebrochen. " & Chr(13) & Chr(13), 16, "Achtung!"
			Exit Sub
		End If
		'*****************************************************************************************************************************************************
		'Extrahierung und Zwischenspeicherung der jeweiligen TAG-Inhalte
		If sCurrentLine <>"" Then
			If Instr(sCurrentLine,"<Client Name=""") = 1 Then
				nCountClient = nCountClient + 1
				sClientName				= findPartString(sCurrentLine,"<Client Name=""",""" Type=""",1)
				sClientType				= findPartString(sCurrentLine,""" Type=""",""">",1)
				
				'sClientName = convertToUnicode(sClientName)
				msgbox sClientName
		'------>
				'Überprüfung, ob in der Tabelle "clients" schon Einträge vorhanden sind...
		'------>
				oResultClients.Command = "SELECT ID, name, type FROM clients WHERE name = '" & sClientName & "'"
				oResultClients.Execute
				if oResultClients.first() = True then msgbox oResultClients.getString(2)
				If oResultClients.First = True Then
					'... falls JA, wird hier die Tabelle auf Übereinstimmung durchsucht
					nClientID = oResultClients.getString(1)
					'msgbox nClientID
				'... falls NICHT, wird ein neuer Datensatz angelegt
				Else
					oResultClients.Command = "SELECT ID, name, type FROM clients ORDER BY ID"
					oResultClients.Execute
					oResultClients.last()
					oResultClients.moveToInsertRow()
					oResultClients.updateString(2, sClientName)
					oResultClients.updateString(3, sClientType)
					oResultClients.insertRow()
					oResultClients.moveToCurrentRow()
					oResultClients.Last()
				End If
				
			ElseIf Instr(sCurrentLine,"<Project Name=""") = 1 Then
				sProjectName			= findPartString(sCurrentLine,"<Project Name=""",""" Type=""",1)
				sProjectType			= findPartString(sCurrentLine,""" Type=""",""" Code=""",1)
				sProjectCode 			= findPartString(sCurrentLine,""" Code=""",""">",1)
			ElseIf Instr(sCurrentLine,"<Task Name=""") = 1 Then
				sTaskName 				= findPartString(sCurrentLine,"<Task Name=""",""" Type=""",1)
				sTaskType 				= findPartString(sCurrentLine,""" Type=""",""" Code=""",1)
				sTaskCode 				= findPartString(sCurrentLine,""" Code=""",""" Location=""",1)
				sTaskLocation 			= findPartString(sCurrentLine,""" Location=""",""">",1)
			ElseIf Instr(sCurrentLine,"<Description>") = 1 Then
				sTaskDescription		= findPartString(sCurrentLine,"<Description>","</Description>",1)				'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<noch ausarbeiten!
			ElseIf Instr(sCurrentLine,"<Timecard Start=""") = 1 Then
				sTimecardStart			= findPartString(sCurrentLine,"<Timecard Start=""",""" Final=""",1)
				sTimecardFinal			= findPartString(sCurrentLine,""" Final=""",""" Workbreak=""",1)
				nTimecardWorkbreak		= CDbl(findPartString(sCurrentLine,""" Workbreak=""",""">",1))/3600
			ElseIf Instr(sCurrentLine,"<Details>") = 1 Then
				sTimecardDetails		= findPartString(sCurrentLine,"<Details>","</Details>",1)
			ElseIf Instr(sCurrentLine,"<Description>") = 1 Then
				sTimecardDescription	= findPartString(sCurrentLine,"<Description>","</Description>",1)				'<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<noch ausarbeiten!
			End If
			
			'sText = sText & sCurrentLine & Chr(13)
		End If
	Loop
	
	'Datei schließen
	Close #nFileNo
	'*********************************************************************************************************************************************************
	'Erstellung einer Sicherungskopie der SQLite-Datenbank
	call databaseBackup()
	
	'Msgbox sText
	'Msgbox sClientName & Chr(13) & sClientTyp
	'Msgbox sProjectName & Chr(13) & sProjectType & Chr(13) & sProjectCode
	'Msgbox sTaskName & Chr(13) & sTaskType & Chr(13) & sTaskCode & Chr(13) & sTaskLocation & Chr(13) & sTaskDescription
	'Msgbox sTimecardStart & Chr(13) & sTimecardFinal & Chr(13) & nTimecardWorkbreak & Chr(13) & sTimecardDetails & Chr(13) & sTimecardDescription
End Sub
sClientName wird nach Zuweisung aus sCurrentline (in der Mitte des Codes) in die Messagebox geladen.

LG,

Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

Re: SQLite Format Problem

Beitrag von marcel_at_work »

Uuuuuuuunnddd... ;-)

... keinen Rat?

LG, Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
pmoegenb
********
Beiträge: 4330
Registriert: Di, 22.06.2004 12:02
Wohnort: 71134 Aidlingen
Kontaktdaten:

Re: SQLite Format Problem

Beitrag von pmoegenb »

Hallo Marcel,
Du schreibst nicht, ob es sich um eine SQLite2- oder SQLite3-Datenbank handelt. Ich bin mir nicht sicher ob SQLite2 bereits die Zeichencodierung UTF-8 kannte. Bei SQLite3 ist UTF-8 der Defaultwert.
Gruß

Peter
---------------------------------------------------------------------------
Windows 7 Prof. 64-bit SP1, LibreOffice 4.3.6.2 und AOO 4.1.1
marcel_at_work
****
Beiträge: 195
Registriert: Sa, 24.04.2010 15:51
Wohnort: Basel [CH]

Re: SQLite Format Problem

Beitrag von marcel_at_work »

Hallo Peter,

ich arbeite mit SQLite3.

Das Problem habe ich diese Nacht schön gelöst, hatte nur noch keine Zeit, zu antworten. Sorry.

Ich habe mir dazu eine kleine Tabelle angelegt und dort sämtliche Sonderzeichen, die Probleme bereiten, eingetragen. Also die tatsächlichen Symbole nebst der Hyroglyphen, die am anderen Ende herauskommen.
Und mittels zwei kleiner Schleifen wandle ich jetzt einfach die fehlerhaften Symbole um, einmal zu Unicode, direkt nach Einbindung der XML-Daten, und dann wieder von Unicode zurück, direkt vor der Übertragung in die Datenbank. Dies dauert nun zwar ein paar Takte länge, liegt aber noch im Rahmen meiner Anwendung.

Code: Alles auswählen

Dim i As Long
	
For i = 1 To nResultUnicodesMAX
	oResultUnicodes.Absolute(i)
	sString = replaceString(sString,oResultUnicodes.getString(1),oResultUnicodes.getString(2))
Next i

Danke und einen wundervollen Abend noch,

Marcel
[Win 10 Pro x64/Downgrade 7, AOO 4.1.6 und LO 6.3.0.4]
Antworten