Wow, diese Einschränkungen sind ziemlich einschränkend, aber ich denke, es gibt einen Weg, sie zu umgehen. Ich denke, Sie müssen vielleicht Ihr eigenes kleines Skript dafür schreiben.
Ich würde selbst Java mit JDBC verwenden (aber jede Sprache, die eine Verbindung zur Datenbank herstellen und diese lesen und Zeichenfolgen ausgeben kann, reicht aus), um ein kleines Programm zu schreiben, das einen Datensatz jeder Zeile in der Datenbank abruft. Dann für jede dieser Zeilen:
-
Erstellen Sie eine Einfügeanweisung mit den vollständigen Daten. Wenn dies weniger als 2.000 Bytes sind, geben Sie es einfach in die Datei aus und fahren Sie mit der nächsten Zeile fort.
-
Erstellen Sie andernfalls eine Einfügeanweisung für jedes Feld, aber lassen Sie
c13
Feld als''
(leer). -
Dann, solange Ihr
c13input
string größer als 2000 Zeichen ist, geben Sie eine Update-Anweisung der Form"update tbl set c13 = c13 || '" + c13input.substring (0,2000) + "' where ..."
aus (Anhängen der nächsten 2000 Zeichen) und dannc13input = c13input.substring(2000)
um diese Zeichen aus Ihrer Zeichenfolge zu entfernen. -
Einmal
c13input
weniger als oder gleich 2000 Zeichen lang ist, gib einfach ein letztes Update aus, um es am Ende anzuheften.
Auf diese Weise können Sie Ihre einzelnen SQL-Anweisungen um die 2000-Zeichen-Marke halten und effizient die richtige SQL ausführen, um eine andere Datenbanktabelle neu zu füllen.
Das ist die Art von Dingen, über die ich spreche (für eine Tabelle, die nur einen Primärschlüssel c1
enthält und ein großes hupendes varchar c13
):
rowset r = db.exec ("select * from oldtable");
while r.next != NO_MORE_ROWS:
string s = "insert into newtable (c1,c13) values ('" +
r.get("c1") + "','" + r.get("c13") + "')"
if s.len() < 2000:
print s
else:
s = "insert into newtable (c1,c13) values ('" + r.get("c1") + "','')"
print s
f = r.get("c13")
while f.len() > 2000:
s = "update newtable set c13 = c13 || '" + f.substring(0,2000) + ')"
f = f.substring(2000)
print s
endwhile
s = "update newtable set c13 = c13 || '" + f + ')"
print s
endif
endwhile
Offensichtlich müssen Sie die Zeichenfolgen möglicherweise morphen, um das Einfügen von Sonderzeichen zu ermöglichen - ich bin mir nicht sicher, in welchem Format Oracle diese erwartet, aber es wäre hoffentlich eine einfache Sache, die Zeichenfolgen zu übergeben (r.get("c13")
wenn die Länge der vollständigen Einfügung kleiner als 2000 ist, f.substring(0,2000)
und f
wenn Sie auch Updates erstellen) an eine Hilfsfunktion, um dies zu tun.
Wenn dieses Morphing wahrscheinlich die Größe der gedruckten Zeile erhöht, sollten Sie den Schwellenwert sicherheitshalber auf 1000 zurücksetzen, um sicherzustellen, dass der gemorphte String nicht zu einer Zeile führt, die größer als das PL/SQL-Limit ist.
Tut mir leid, wenn das verworren erscheint, aber die Einschränkungen, die Sie angegeben haben, lähmen uns ein wenig. Es gibt vielleicht einen besseren Weg, aber ich kann mir keinen vorstellen, der alle erfüllt Ihre Kriterien.
Aktualisieren: Anscheinend bist du sogar noch mehr gelähmt als ursprünglich gedacht:wenn man sich beim Generieren auf SQL beschränken muss sowohl das Skript als auch das Ausführen, es gibt einen Weg, so qualvoll er auch ist.
Sie können SQL verwenden, um SQL zu generieren. Verwenden Sie meine oben erwähnte Tabelle mit c1
und c13
, können Sie Folgendes tun:
select
'insert into newtable (c1,c13) values ("' ||
c1 ||
'","");'
from oldtable;
# Xlates to: insert into newtable (c1,c13) values ("[c1]","");
Dadurch erhalten Sie alle Ihre Basiswerte insert
Anweisungen zum Duplizieren von allem außer dem c13
Spalte.
Was Sie dann tun müssen, ist, weitere Anweisungen zum Setzen von c13
zu generieren . Um c13
zu aktualisieren für alle Werte der Länge 1000 oder weniger (einfache Menge):
select
'update newtable set c13 = "' ||
c13 ||
'" where c1 = "' ||
c1 ||
'";'
from oldtable where length(c13) <= 1000;
# Xlates to: update newtable set c13 = "[c13]" where c1 = "[c1]";
# but only for rows where length([c13]) <= 1000
Dann zum update
c13 für alle Werte zwischen 1001 und 2000 Zeichen (einstellen und dann anhängen):
select
'update newtable set c13 = "' ||
substring(c13,1,1000) ||
'" where c1 = "' ||
c1 ||
'";'
from oldtable where length(c13) > 1000 and length(c13) <= 2000;
select
'update newtable set c13 = c13 || "' ||
substring(c13,1001,1000) ||
'" where c1 = "' ||
c1 ||
'";'
from oldtable where length(c13) > 1000 and length(c13) <= 2000;
# Xlates to: update newtable set c13 = "[c13a]" where c1 = "[c1]";
# update newtable set c13 = c13 || "[c13b]" where c1 = "[c1]";
# but only for rows where length([c13]) > 1000 and <= 2000
# and [c13a]/[c13b] are the first/second thousand chars of c13.
Und so weiter für diejenigen, die 2001 bis 3000 und 3001 bis 4000 lang sind.
Da muss wohl noch etwas nachgebessert werden. Ich gebe Ihnen gerne einen Lösungsweg, aber mein Wunsch, an einer solchen Monstrosität bis zur Fertigstellung zu arbeiten, ist bestenfalls minimal :-)
Wird es die Arbeit erledigen? Ja. Ist es hübsch? Ich würde sagen, das war ein klares "NEIN!" aber angesichts Ihrer Einschränkungen ist das vielleicht das Beste, worauf Sie hoffen können.
Als Proof-of-Concept ist hier ein SQL-Skript in DB2 (jedoch keine besonderen Funktionen, es sollte in jedem DBMS mit einer length
gut funktionieren und substr
Äquivalent):
# Create table and populate.
DROP TABLE XYZ;
COMMIT;
CREATE TABLE XYZ (F1 VARCHAR(1),F2 VARCHAR(20));
COMMIT;
INSERT INTO XYZ VALUES ('1','PAX');
INSERT INTO XYZ VALUES ('2','GEORGE');
INSERT INTO XYZ VALUES ('3','VLADIMIR');
INSERT INTO XYZ VALUES ('4','ALEXANDRETTA');
SELECT * FROM XYZ ORDER BY F1;
# Create initial insert statem,ents.
SELECT 'INSERT INTO XYZ (F1,F2) VALUES (' || F1 ','''');'
FROM XYZ;
# Updates for 1-5 character F2 fields.
SELECT 'UPDATE XYZ SET F2 = ''' || F2 ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) <= 5;
# Updates for 6-10 character F2 fields.
SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6) ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
# Updates for 11-15 character F2 fields.
SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6,5) ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,11) ||
''' WHERE F1 = ''' || F1 || ''';'
FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
und dies erzeugt die folgenden Zeilen:
> DROP TABLE XYZ;
> COMMIT;
> CREATE TABLE XYZ (F1 VARCHAR(1),F2 VARCHAR(20));
> COMMIT;
> INSERT INTO XYZ VALUES ('1','PAX');
> INSERT INTO XYZ VALUES ('2','GEORGE');
> INSERT INTO XYZ VALUES ('3','VLADIMIR');
> INSERT INTO XYZ VALUES ('4','ALEXANDRETTA');
> SELECT * FROM XYZ;
F1 F2
-- ------------
1 PAX
2 GEORGE
3 VLADIMIR
4 ALEXANDRETTA
> SELECT 'INSERT INTO XYZ (F1,F2) VALUES (' || F1 || ','''');'
> FROM XYZ;
INSERT INTO XYZ (F1,F2) VALUES (1,'');
INSERT INTO XYZ (F1,F2) VALUES (2,'');
INSERT INTO XYZ (F1,F2) VALUES (3,'');
INSERT INTO XYZ (F1,F2) VALUES (4,'');
> SELECT 'UPDATE XYZ SET F2 = ''' || F2 ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) <= 5;
UPDATE XYZ SET F2 = 'PAX' WHERE F1 = '1';
> SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
UPDATE XYZ SET F2 = 'GEORG' WHERE F1 = '2';
UPDATE XYZ SET F2 = 'VLADI' WHERE F1 = '3';
> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 5 AND LENGTH(F2) <= 10;
UPDATE XYZ SET F2 = F2 || 'E' WHERE F1 = '2';
UPDATE XYZ SET F2 = F2 || 'MIR' WHERE F1 = '3';
> SELECT 'UPDATE XYZ SET F2 = ''' || SUBSTR(F2,1,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
UPDATE XYZ SET F2 = 'ALEXA' WHERE F1 = '4';
> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,6,5) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
UPDATE XYZ SET F2 = F2 || 'NDRET' WHERE F1 = '4';
> SELECT 'UPDATE XYZ SET F2 = F2 || ''' || SUBSTR(F2,11) ||
> ''' WHERE F1 = ''' || F1 || ''';'
> FROM XYZ WHERE LENGTH(F2) > 10 AND LENGTH(F2) <= 15;
UPDATE XYZ SET F2 = F2 || 'TA' WHERE F1 = '4';
Brechen wir die Ausgabezeilen heraus, erhalten wir:
INSERT INTO XYZ (F1,F2) VALUES (1,'');
INSERT INTO XYZ (F1,F2) VALUES (2,'');
INSERT INTO XYZ (F1,F2) VALUES (3,'');
INSERT INTO XYZ (F1,F2) VALUES (4,'');
UPDATE XYZ SET F2 = 'PAX' WHERE F1 = '1';
UPDATE XYZ SET F2 = 'GEORG' WHERE F1 = '2';
UPDATE XYZ SET F2 = 'VLADI' WHERE F1 = '3';
UPDATE XYZ SET F2 = F2 || 'E' WHERE F1 = '2';
UPDATE XYZ SET F2 = F2 || 'MIR' WHERE F1 = '3';
UPDATE XYZ SET F2 = 'ALEXA' WHERE F1 = '4';
UPDATE XYZ SET F2 = F2 || 'NDRET' WHERE F1 = '4';
UPDATE XYZ SET F2 = F2 || 'TA' WHERE F1 = '4';
was Ihnen die ursprünglichen Zeilen geben sollte, wenn auch auf Umwegen.
Und das ist ungefähr so viel Mühe, wie ich in eine einzelne Frage stecken kann, ohne dass mein Gehirn kocht, also sage ich Ihnen adieu, es sei denn, ich werde auf schwerwiegende Fehler hingewiesen.
Viel Glück mit Ihrem Projekt und die besten Wünsche.