Ich lese in ein Blob-Feld Typ 1 eine ordinäre CSV-Datei ein.
Diese möchte ich zeilenweise verarbeiten.
Die Zeilen haben keine feste Länge, aber eine feste Feldstruktur. z.B.
id;Entity1;Entity2;IntWert1;IntWert2
Die Feldlängen selbst sind variabel. Das Separieren der einzelnen Feldwerte ist trivial, habe ich ordentlich im Griff.
Habe ich irgendeine Chance (ohne externe Libs), an die einzelnen Zeilen des Blobs zu kommen? Also so eine Art ReadLn...
Ein weiteres Problem ist noch, das ich nicht weiß, wie der Zeilenumbruch aussieht: #10 oder #13#10 oder #13?
Sonst hätte ich es sinngemäß so gemacht:
sub_string(blobfeld from 1 for position(endezeichen));
Klar das ab der nächsten Zeile die letzte Endposition+1 nun die neue Startposition wäre, geschenkt.
Schreibe ich die Zeilen einzeln in die DB, dauert das bei gut 100.000 Sätze über 2Min, als Blob ist die Datei in nicht mal 1 Sekunde in der DB.
Zeilenweise Verarbeitung eines TextBlobs
Moderator: thorben.braun
- martin.koeditz
- Beiträge: 500
- Registriert: Sa 31. Mär 2018, 14:35
N'Abend,
in Firebird lässt sich der Zeilenumbruch wie folgt darstellen:
Gruß
Martin
in Firebird lässt sich der Zeilenumbruch wie folgt darstellen:
Hiermit sollte sich das Zeilenende ermitteln lassen.ASCII_CHAR(13)||ASCII_CHAR(10)
Gruß
Martin
Martin Köditz
SynDesk SW GmbH
SynDesk SW GmbH
Hallo Martin,
vielen Dank für Deine schnelle Antwort.
Das Problem ist aber, dass ich nicht weiß, in welchem Format innerhalb des Blobs die Zeilenumbrüche vorliegen.
Dass es normalerweise ASCII_CHAR(13)||ASCII_CHAR(10) sein sollte, ist mir schon klar. Aber das ist es nicht immer, sondern manchmal nur ASCII_CHAR(13) oder nur ASCII_CHAR(10). Abgesehen davon, wollte ich nicht selbst die Zeilenumbrüche ausrechnen.
Gibt es in der Tat keine Möglichkeit, Text_Blobs sinngemäß wie eine Stringliste, Memo o.ä. auszulesen?
vielen Dank für Deine schnelle Antwort.
Das Problem ist aber, dass ich nicht weiß, in welchem Format innerhalb des Blobs die Zeilenumbrüche vorliegen.
Dass es normalerweise ASCII_CHAR(13)||ASCII_CHAR(10) sein sollte, ist mir schon klar. Aber das ist es nicht immer, sondern manchmal nur ASCII_CHAR(13) oder nur ASCII_CHAR(10). Abgesehen davon, wollte ich nicht selbst die Zeilenumbrüche ausrechnen.
Gibt es in der Tat keine Möglichkeit, Text_Blobs sinngemäß wie eine Stringliste, Memo o.ä. auszulesen?
Du kannst den Blob ja auslesen und per Split-Funktion deiner Programmiersprache in Zeilen auflösen.
Beispiel für .Net:
string.split(var, new char[] {'\n', '\r'})
Außerdem:
Per Bulk.Insert (bis 255 Inserts in einem SQL) schafft man 100.000 Zeilen in 5 Sekunden oder sogar kürzer. Auch bereits mit 2.5.
Wichtig ist jedoch die Erkenntnis, dass Parametermarker "?" das Tempo erhöhen.
Beispiel für .Net:
string.split(var, new char[] {'\n', '\r'})
Außerdem:
Per Bulk.Insert (bis 255 Inserts in einem SQL) schafft man 100.000 Zeilen in 5 Sekunden oder sogar kürzer. Auch bereits mit 2.5.
Wichtig ist jedoch die Erkenntnis, dass Parametermarker "?" das Tempo erhöhen.
Hallo zappa2,
Du kannst diese SP dafür einsetzen (die ist auch sonst ganz nützlich):
Das Zeilenende kannst Du einmalig aus der ersten Zeile ermitteln und dann als token an split übergeben.
Grüße, vr2
Du kannst diese SP dafür einsetzen (die ist auch sonst ganz nützlich):
Code: Alles auswählen
CREATE PROCEDURE SPLIT (
TEXT BLOB SUB_TYPE 1 SEGMENT SIZE 80,
TOKEN VARCHAR(100)
)
RETURNS (
PART VARCHAR(32000),
POS INTEGER
)
AS
declare newpos int;
declare oldpos int;
declare len int;
begin
oldpos = 1;
newpos = 1;
pos = 0;
len = char_length(token);
while (1 = 1) do
begin
newpos = position(token, text, oldpos);
if (newpos > 0) then
begin
part = substring(text from oldpos for newpos - oldpos);
pos = pos + 1;
suspend;
oldpos = newpos + len;
end
else if (oldpos - len <= char_length(text)) then
begin
part = substring(text from oldpos);
pos = pos + 1;
suspend;
break;
end
else
break;
end
end;
Grüße, vr2