Discussion:
Probleme beim Umzug von Access nach SQL
(zu alt für eine Antwort)
Stefan Koschke
2011-04-11 12:47:53 UTC
Permalink
Hallo zusammen,

endlich habe es die Anwender eingesehen, ich darf mein Programm von
Access-Datenbanken nach SQL-Server umstellen.
Dafür habe ich mir ein Importtool geschaffen, welches per
INSERT INTO ... SELECT * FROM ... OPENROWSET(BULK...)... (
FORMATFILE=....) as Importdata
die Access-Daten umschaufelt.
Hierfür wird jeweils eine Textdatei mit den Daten und eine Formatdatei
übergeben.

Hier ein Beispiel Text:
8 Rödenthal Daniel Hatzel .....
9 Rödenthal Schule Rödental Mitte ....

und die xml-Formatdatei
<BCPFORMAT
xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="6" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="7" xsi:type="CharTerm" TERMINATOR="\t"/>
<FIELD ID="8" xsi:type="CharTerm" TERMINATOR="\r\n"/>
</RECORD>
<ROW>
<COLUMN SOURCE="2" NAME="Kundennummer" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="3" NAME="Name" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="4" NAME="Adresse" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="5" NAME="PLZ" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="6" NAME="Ort" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="7" NAME="Zusatz" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="8" NAME="geloescht" xsi:type="SQLBIT"/>
</ROW>
</BCPFORMAT>

Kundennummer und name sind in der felddefinition gleich, auch in der
zugehörigen SQL-Tabelle.
Aber "Rödental" in der ersten Textspalte erscheint in beiden Datensätzen
korrekt, "Schule Rödental Mitte" in der zweiten Spalte hat einen
falschen Umlaut ö in der Datenbank!

Ich habe keine Ahnung, wo ich ansetzen könnte, hat jemand bitte eine Idee?

Ciao
Stefan
Michael Broede
2011-04-11 15:16:12 UTC
Permalink
Hi,
Post by Stefan Koschke
Hallo zusammen,
endlich habe es die Anwender eingesehen, ich darf mein Programm von
Access-Datenbanken nach SQL-Server umstellen.
Dafür habe ich mir ein Importtool geschaffen, welches per
INSERT INTO ... SELECT * FROM ... OPENROWSET(BULK...)... (
FORMATFILE=....) as Importdata
die Access-Daten umschaufelt.
Hierfür wird jeweils eine Textdatei mit den Daten und eine Formatdatei
übergeben.
...
leider habe ich keine konkrete Antwort auf Deine Frage. Nach meinen
Erfahrungen kommen bei der Übernahme von Daten in den SQL-Server solche
Fehler eben vor. Gerade wenn Du mit Textdateien oder so hantierst. Da
wird gern auch mal ein Datum wie der 01.12. zum zwölften Januar. Ich
rate von so einem Importverfahren via Dateihandling ab.
Wenn Du die Möglichkeit hast, verwende den Import-Assistenten des
SQL-Servers [1]. Der funktioniert zwar auch nur etwas holprig, aber
zumindest kann man was konfigurieren. Und Du vergibst nicht den einen
Vorteil, den Dir Access schon bietet: eingebaute feste Datentypen.
Alternativ kannst Du auch anders herum aus Access heraus die Tabellen
mittels ODBC an den SQL-Server übertragen. Unter Access 2010 gibts sogar
einen Upsizing-Assistenten.

Bye

Michael


[1] In der MS-SQL-Management-Konsole rechte Maustaste auf der Datenbank,
Menüpunkt "Tasks / Daten importieren" auswählen, Datenquelle "Microsoft
Access" auswählen, Datenbankdatei auswählen usw., am Ende die zu
importierenden Tabellen ankreuzen, Import starten und fertig.
Stefan Koschke
2011-04-12 05:55:06 UTC
Permalink
Post by Michael Broede
leider habe ich keine konkrete Antwort auf Deine Frage. Nach meinen
Erfahrungen kommen bei der Übernahme von Daten in den SQL-Server solche
Fehler eben vor. Gerade wenn Du mit Textdateien oder so hantierst. Da
wird gern auch mal ein Datum wie der 01.12. zum zwölften Januar. Ich
rate von so einem Importverfahren via Dateihandling ab.
Wenn Du die Möglichkeit hast, verwende den Import-Assistenten des
SQL-Servers [1]. Der funktioniert zwar auch nur etwas holprig, aber
zumindest kann man was konfigurieren. Und Du vergibst nicht den einen
Vorteil, den Dir Access schon bietet: eingebaute feste Datentypen.
Alternativ kannst Du auch anders herum aus Access heraus die Tabellen
mittels ODBC an den SQL-Server übertragen. Unter Access 2010 gibts sogar
einen Upsizing-Assistenten.
Hallo Michael,

beide Varianten scheiden aus, ich brauche ein Tool wo der Anwender den
Pfad der Access-Dateien einträgt sowie die SQL-Zugangsparameter
(Datenbankname, User, Pwd...) und einen Knopf drückt, alles andere muß
automatisch laufen, ich habe Anwender die "ansonsten keine Ahnung von
EDV haben" bzw. weit im Ausland sitzen.
Ich habe ja schon eine Lösung mit den Komponenten von EMS, die sind
allerdings Faktor 10 langsamer als der Import per INSERT INTO mit Bulk,
aber da sind alle Felder richtig gefüllt.
Dann dauert es eben länger ;-)
Trotzdem danke für den Tip!

Ciao
Stefan
Nicole Wagner
2011-04-12 13:53:23 UTC
Permalink
Post by Stefan Koschke
Kundennummer und name sind in der felddefinition gleich, auch in der
zugehörigen SQL-Tabelle. Aber "Rödental" in der ersten Textspalte
erscheint in beiden Datensätzen korrekt, "Schule Rödental Mitte" in
der zweiten Spalte hat einen falschen Umlaut ö in der Datenbank!
Ich habe keine Ahnung, wo ich ansetzen könnte, hat jemand bitte eine Idee?
1) Auf welche Zeichensaetze hast Du denn in den DBs jeweils eingestellt?

2) Vor "Name" sei gewarnt. Das ist ein reserviertes Wort, wenn ich
nicht irre, zumindest in Firbird.


Ncole
Stefan Koschke
2011-04-13 06:00:47 UTC
Permalink
Post by Nicole Wagner
2) Vor "Name" sei gewarnt. Das ist ein reserviertes Wort, wenn ich
nicht irre, zumindest in Firbird.
weder Access noch SQL-Server 2008 nörgeln an Name herum :-)

Ciao
Stefan
Sascha Riepel
2011-04-13 08:23:10 UTC
Permalink
Hallo,


Wenn ich sich richtig verstanden habe, willst du ausschließlich die Daten von Access nach MS-SQL bringen, oder?
Wenn ja, warum machst du es nicht manuell. Als Beispiel nehme ich eine Tabelle deren Tabellen- und Feldnamen identisch
sind.

procedure CopyTable;
var
AccessTable, SlqTable: TAdoTable;
i: Integer;
begin
AccessTable.Connection := AccessConnection;
AccessTable.TableName := 'Tabelle1';
AccessTable.Open;
SqlTable.Connection := SqlConnection;
SqlTable.TableName := 'Tabelle1';
SqlTable.Open;

AccessTable.First;
while not AccessTable.Eof do
begin
SqlTable.Insert;
for i := 0 to AccessTable.FieldCount-1 do
begin
if SqlTable.FindField(AccessTable.Fields[i].FieldName) <> nil then
SqlTable.FindField(AccessTable.Field[i].FieldName).Value := AccessTable.Fields[i].Value;
end;
SqlTable.Post;
AccessTable.Next;
end;
end;

ich weiß, meine Antwort ist sicher nicht die beste und die schnellste, sollte aber auch mit den Umlauten funktionieren.

Gruß Sascha.
Stefan Koschke
2011-04-13 08:33:01 UTC
Permalink
Post by Sascha Riepel
Hallo,
Wenn ich sich richtig verstanden habe, willst du ausschließlich die
Daten von Access nach MS-SQL bringen, oder?
Wenn ja, warum machst du es nicht manuell. Als Beispiel nehme ich eine
Tabelle deren Tabellen- und Feldnamen identisch sind.
procedure CopyTable;
var
AccessTable, SlqTable: TAdoTable;
i: Integer;
begin
AccessTable.Connection := AccessConnection;
AccessTable.TableName := 'Tabelle1';
AccessTable.Open;
SqlTable.Connection := SqlConnection;
SqlTable.TableName := 'Tabelle1';
SqlTable.Open;
AccessTable.First;
while not AccessTable.Eof do
begin
SqlTable.Insert;
for i := 0 to AccessTable.FieldCount-1 do
begin
if SqlTable.FindField(AccessTable.Fields[i].FieldName) <> nil then
SqlTable.FindField(AccessTable.Field[i].FieldName).Value :=
AccessTable.Fields[i].Value;
end;
SqlTable.Post;
AccessTable.Next;
end;
end;
ich weiß, meine Antwort ist sicher nicht die beste und die schnellste,
sollte aber auch mit den Umlauten funktionieren.
Hallo Sascha.

Du gehts richtig in der Annahme daß es eine Einbahnstraße sit, nur von
Access nach SQL-Server.
Klar geht Deine Lösung, damit hatte ich schon angefangen ;-)
Nur ist das "ewig langsam" im Gegensatz zu Bulk insert per Dateien!
Obige Lösung ist (warum auch immer) langsamer als den Import per
EMS-Komponenten zu machen.
Letztendlich würde ich gern wieder zu Bulk insert zurück weil es eben
superschnell funktioniert...

Ach so, das feld Name im Beispiel ist keinesfalls die Ursache, ich habe
in anderen textfeldern ebenfalls falsche Umlaute gefunden.

Ciao
Stefan
Sascha Riepel
2011-04-13 09:22:56 UTC
Permalink
Hallo,
Ach so, das feld Name im Beispiel ist keinesfalls die Ursache, ich habe in anderen textfeldern ebenfalls falsche
Umlaute gefunden.
Dann vermute ich mal, dass es Probleme mit der Umwandlung von ANSI nach Unicode gibt.
Kannst du deine Datei als Unicode speichern und probieren wie es dann aussieht?

Gruß Sascha.
Stefan Koschke
2011-04-13 09:50:18 UTC
Permalink
Post by Sascha Riepel
Hallo,
Post by Stefan Koschke
Ach so, das feld Name im Beispiel ist keinesfalls die Ursache, ich
habe in anderen textfeldern ebenfalls falsche Umlaute gefunden.
Dann vermute ich mal, dass es Probleme mit der Umwandlung von ANSI nach Unicode gibt.
Kannst du deine Datei als Unicode speichern und probieren wie es dann aussieht?
Die Übergabe-Textdatei wird in einem Tstrings zusammengestellt (D2010)
und sollte damit Unicode sein?
Was passiert dann bei ..SaveToFile(fn) ?
Wird da wieder Ansi draus, ich denke nicht, oder doch?

Ciao
Stefan
Sascha Riepel
2011-04-13 10:13:38 UTC
Permalink
Hallo,
Die Übergabe-Textdatei wird in einem Tstrings zusammengestellt (D2010) und sollte damit Unicode sein?
Was passiert dann bei ..SaveToFile(fn) ?
Wird da wieder Ansi draus, ich denke nicht, oder doch?
Mangels D2010 kann ich das nicht testen.
Aber vielleicht kannst du mal probieren, die Datei im Notepad od. besseren Editor zu öffnen und explizit als
Unicode/Utf-8 zu speichern.

Gruß Sascha.
Arno Garrels
2011-04-13 10:22:22 UTC
Permalink
Post by Stefan Koschke
Post by Sascha Riepel
Hallo,
Post by Stefan Koschke
Ach so, das feld Name im Beispiel ist keinesfalls die Ursache, ich
habe in anderen textfeldern ebenfalls falsche Umlaute gefunden.
Dann vermute ich mal, dass es Probleme mit der Umwandlung von ANSI nach Unicode gibt.
Kannst du deine Datei als Unicode speichern und probieren wie es dann aussieht?
Die Übergabe-Textdatei wird in einem Tstrings zusammengestellt (D2010)
und sollte damit Unicode sein?
Was passiert dann bei ..SaveToFile(fn) ?
Wird da wieder Ansi draus, ich denke nicht, oder doch?
Es wird wieder nach Ansi konvertiert, falls man kein explizites Encoding
angibt, wie z.B. AStringList.SaveToFile('Dateiname', TEncoding.UTF8).
Aber ich vermute mal, dass schon in der Stringlist falsche Zeichen
stehen bzw. schon in der Access Tabelle.
--
Arno Garrels
Nicole Wagner
2011-04-13 18:44:56 UTC
Permalink
Post by Stefan Koschke
Post by Sascha Riepel
Hallo,
Post by Stefan Koschke
Ach so, das feld Name im Beispiel ist keinesfalls die Ursache, ich
habe in anderen textfeldern ebenfalls falsche Umlaute gefunden.
Dann vermute ich mal, dass es Probleme mit der Umwandlung von ANSI nach Unicode gibt.
Kannst du deine Datei als Unicode speichern und probieren wie es dann aussieht?
Die Übergabe-Textdatei wird in einem Tstrings zusammengestellt
(D2010) und sollte damit Unicode sein? Was passiert dann bei
..SaveToFile(fn) ? Wird da wieder Ansi draus, ich denke nicht, oder
doch?
Ciao
Stefan
Also bei mir funktioniert das nicht so einfach.
Ich habe, wenn ich eine DB mit IBExperts registriere, eine recht lange
Auswahl von verschiedenen CharSets.

Gefuehlsmaessig wuerde ich sagen, man sollte primaer mal pruefen, ob
die beiden Sets bei Deinen DB-Registrierungen ident sind. Ich denke
fast nein.


Nicole
Frank Rothweiler
2011-04-13 11:12:28 UTC
Permalink
Post by Stefan Koschke
8 Rödenthal Daniel Hatzel .....
9 Rödenthal Schule Rödental Mitte ....
<COLUMN SOURCE="2" NAME="Kundennummer" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="3" NAME="Name" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="4" NAME="Adresse" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="5" NAME="PLZ" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="6" NAME="Ort" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="7" NAME="Zusatz" xsi:type="SQLVARYCHAR"/>
<COLUMN SOURCE="8" NAME="geloescht" xsi:type="SQLBIT"/>
</ROW>
</BCPFORMAT>
Kundennummer und name sind in der felddefinition gleich, auch in der
zugehörigen SQL-Tabelle.
Aber "Rödental" in der ersten Textspalte erscheint in beiden Datensätzen
korrekt, "Schule Rödental Mitte" in der zweiten Spalte hat einen
falschen Umlaut ö in der Datenbank!
Hast du einmal überprüft, ob die Felddefinitionen in der Zieldatenbank
hinsichtlich Zeichensatz identisch sind? Ich hatte einmal ein ähnliches
Problem – Quelle: Access-Datenbank, Ziel: Firebird-Datenbank. Beim
Einrichten der Firebird-Datenbank hatte ich einen Fehler gemacht und
einer Spalte nicht den richtigen Zeichensatz zugewiesen. Ergo gab es in
dieser Spalte keine Umlaute.
Stefan Koschke
2011-04-13 12:45:39 UTC
Permalink
Post by Frank Rothweiler
Hast du einmal überprüft, ob die Felddefinitionen in der Zieldatenbank
hinsichtlich Zeichensatz identisch sind? Ich hatte einmal ein ähnliches
Problem – Quelle: Access-Datenbank, Ziel: Firebird-Datenbank. Beim
Einrichten der Firebird-Datenbank hatte ich einen Fehler gemacht und
einer Spalte nicht den richtigen Zeichensatz zugewiesen. Ergo gab es in
dieser Spalte keine Umlaute.
Hallo Frank,

da werde ich mich mal als nächstes durchwühlen, ich vermute aber keine
Unterschiede weil alle Tabellen und Felder in der SQL-Datenbank auch per
Code mit "Create Table ... NVARCHAR" angelegt werden, da wird nirgends
(und damit auch nicht unterschiedlich) ein Zeichensatz vorgegeben.
Und in den Formatdateien finde ich ebenfalls keine Angabe (und damit
auch nicht für verschiedene Felder unterschiedlich) zum Zeichensatz :-(

Ciao
Stefan
Frank Rothweiler
2011-04-13 13:07:01 UTC
Permalink
Post by Stefan Koschke
Post by Frank Rothweiler
Hast du einmal überprüft, ob die Felddefinitionen in der Zieldatenbank
hinsichtlich Zeichensatz identisch sind? Ich hatte einmal ein ähnliches
Problem – Quelle: Access-Datenbank, Ziel: Firebird-Datenbank. Beim
Einrichten der Firebird-Datenbank hatte ich einen Fehler gemacht und
einer Spalte nicht den richtigen Zeichensatz zugewiesen. Ergo gab es in
dieser Spalte keine Umlaute.
Hallo Frank,
da werde ich mich mal als nächstes durchwühlen, ich vermute aber keine
Unterschiede weil alle Tabellen und Felder in der SQL-Datenbank auch per
Code mit "Create Table ... NVARCHAR" angelegt werden, da wird nirgends
(und damit auch nicht unterschiedlich) ein Zeichensatz vorgegeben.
Und in den Formatdateien finde ich ebenfalls keine Angabe (und damit
auch nicht für verschiedene Felder unterschiedlich) zum Zeichensatz :-(
Das macht mich jetzt ein wenig stutzig: Du legst alle Felder in der
Zieldatenbank als VARCHAR(n) an? Auch Index- und Datumsspalten?

Ich hatte mal ein Delphi-Projekt angefangen, das jede x-beliebige
Access-Datenbank in eine Firebird-Datenbank kopieren sollte, bin aber
erst einmal daran gescheitert, Einstellungen wie Primärschlüssel oder
NOT NULL aus der Access-Datenbank auszulesen. Daher interessiert es
mich, wie du die Datenbankstruktur deiner Access-Datenbank auf eine
SQL-Datenbank übertragen hast. Vielleicht motiviert mich eine Lösung des
Problems ja am Ende noch dazu, dieses Projekt fortzusetzen ... ;-)
Stefan Koschke
2011-04-14 07:06:13 UTC
Permalink
Post by Frank Rothweiler
Das macht mich jetzt ein wenig stutzig: Du legst alle Felder in der
Zieldatenbank als VARCHAR(n) an? Auch Index- und Datumsspalten?
nein, nein, nein, völliges Mißverständnis ;-)
Klar gibt es auch andere Feldtypen wie Datum, Bit, ...
aber alle diese sind korrekt.
Ich habe die Probleme nur bei den Textfeldern und die sind NVARCHAR,
nicht VARCHAR!

Ciao
Stefan

Loading...