Wow, questi limiti sono piuttosto limitanti, ma penso che potrebbe esserci un modo per aggirarlo. Penso che potresti dover scrivere il tuo piccolo script per questo.
Vorrei usare Java con JDBC da solo (ma qualsiasi linguaggio che possa connettersi e leggere il database e le stringhe di output, lo farà), scrivendo un piccolo programma che recuperava un set di record di ogni riga nel database. Quindi, per ognuna di queste righe:
Costruire una dichiarazione di inserimento con i dati completi. Se questo è inferiore a 2000 byte, devi solo inviarlo al file e passare alla riga successiva.
In caso contrario, creare un'istruzione di inserimento per ogni campo, ma lasciare il campo c13
come ''
(vuoto).
Quindi, fino a quando la stringa c13input
è maggiore di 2000 caratteri, uscita un'istruzione di aggiornamento della forma "update tbl set c13 = c13 || '" + c13input.substring (0,2000) + "' where ..."
(aggiungendo i prossimi 2000 caratteri) e poi fare c13input = c13input.substring(2000)
per togliere quei personaggi dalla stringa.
Una volta che c13input
è inferiore o uguale a 2000 caratteri di lunghezza, è sufficiente emettere un aggiornamento finale per collegarlo alla fine.
Questo permette di mantenere i istruzioni SQL individuali intorno al marchio di 2000 caratteri ed efficiente esegue lo SQL corretto per ripopolare un'altra tabella del database.
Questo è il tipo di cosa sto parlando (per una tabella che contiene solo una chiave primaria c1
e un grande honkin' 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
Ovviamente, potrebbe essere necessario morph le stringhe per consentire inserimenti di caratteri speciali - Non sono sicuro del formato che Oracle si aspetta da questi, ma si spera che sia una semplice questione di passare le stringhe (r.get("c13")
se la lunghezza dell'inserto completo è inferiore a 2000, f.substring(0,2000)
e f
se si stiamo costruendo anche gli aggiornamenti) ad una funzione di aiuto per farlo.
Se è probabile che tale morphing aumenti la dimensione della linea stampata, è possibile che si desideri riportare la soglia a 1000 per essere sicuri, per garantire che la stringa trasformata non risulti in una riga superiore a PL/SQL limite.
Scusa se questo sembra complicato, ma le restrizioni che hai dichiarato ci hanno un po 'ridimensionato. Potrebbe esserci un modo migliore, ma non riesco a pensare a uno che soddisfa tutti i i tuoi criteri.
Aggiornamento: Sembra che tu sei ancora più azzoppato di quanto originariamente pensato: se si deve limitare a SQL per la generazione lo script così come eseguirlo, c'è un modo, per quanto sia tortuoso
È possibile utilizzare SQL per generare SQL. Usando il mio tavolo citato con c1
e c13
, si può fare:
select
'insert into newtable (c1,c13) values ("' ||
c1 ||
'","");'
from oldtable;
# Xlates to: insert into newtable (c1,c13) values ("[c1]","");
che vi darà tutta la vostra linea di base insert
dichiarazioni a duplicare tutto, ma la colonna c13
.
Quello che devi fare è generare più istruzioni per l'impostazione di c13
. Per aggiornare c13
per tutti i valori di lunghezza 1000 o meno (insieme semplice):
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
Poi, per update
C13 per tutti i valori compresi tra 1001 e 2000 caratteri (SET quindi aggiungere):
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.
E così via per quelli che vanno da 2001 a 3000 e da 3001 a 4000 di lunghezza.
Probabilmente ci sarà bisogno di qualche ritocco. Sono felice di darti un modo per risolverlo, ma il mio desiderio di lavorare su una tale mostruosità fino al completamento è minimo nel migliore dei casi :-)
Avrà finito il lavoro? Sì. È carino? Direi che è stato un clamoroso "NO!" ma, dati i tuoi limiti, potrebbe essere il meglio che puoi sperare.
Come una prova di concetto, ecco uno script SQL in DB2 (senza caratteristiche particolari, però, dovrebbe funzionare bene in qualsiasi DBMS che ha un length
e substr
equivalenti):
# 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;
e questo genera le seguenti righe:
> 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';
scoppiare le linee di uscita, otteniamo:
012.351.641,061 mila
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';
che dovrebbe darvi le righe originali, anche se in modo indiretto.
E questo è tanto sforzo come posso mettere in qualsiasi domanda senza il mio friggere il cervello, quindi mi do il adieu a meno che eventuali errori gravi sono segnalati a me.
Buona fortuna per il tuo progetto e auguri.
Un punto non è chiaro e questo è importante. Avete inserimenti/aggiornamenti in cui il * valore * di c13 supera i 2499 caratteri? Oppure, hai semplicemente delle istruzioni in cui la lunghezza dell'istruzione * supera i 2499 caratteri? (Il primo è difficile, il secondo è facile da risolvere) –
La risposta è la seguente: Nella mia tabella Oracle denominata SAMPLE_TABLE, ho 80 record in cui la lunghezza del campo C13, di tipo VARCHAR2 (4000), è 3762 personaggi. Ciò significa che, naturalmente, il VALORE di C13 supera i 2499 caratteri. In questo caso, possiamo osservare che la lunghezza della DICHIARAZIONE supera anche 2499 caratteri. – UltraCommit
@Il pollo in cucina - Qual è la chiave principale del tavolo di destinazione? – Thomas