Уау, тези ограничения са доста ограничаващи, но мисля, че може да има начин да се заобиколи. Мисля, че може да се наложи да напишете свой собствен малък сценарий за това.
Аз самият бих използвал Java с JDBC (но всеки език, който може да се свърже и чете базата данни и изходни низове, ще свърши работа), като напиша малка програма, която извлича набор от записи за всеки ред в базата данни. След това за всеки един от тези редове:
-
Създайте израз за вмъкване с пълните данни. Ако това е по-малко от 2000 байта, просто го изведете във файла и преминете към следващия ред.
-
В противен случай създайте израз за вмъкване за всяко поле, но оставете
c13
поле като''
(празен). -
След това стига вашият
c13input
низът е по-голям от 2000 знака, изведете изявление за актуализиране във формата"update tbl set c13 = c13 || '" + c13input.substring (0,2000) + "' where ..."
(добавяне на следващите 2000 знака) и след това направетеc13input = c13input.substring(2000)
за да премахнете тези знаци от вашия низ. -
Веднъж
c13input
е по-малка или равна на 2000 знака на дължина, просто изведете една последна актуализация, за да я закрепите в края.
Това ви позволява да запазите индивидуалните си SQL изрази около знака от 2000 знака и ефективно да изпълните правилния SQL за повторно попълване на друга таблица на база данни.
Това е типът неща, за които говоря (за таблица, съдържаща само първичен ключ c1
и голям 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
Очевидно може да се наложи да преобразувате низовете, за да позволите вмъкване на специални символи - не съм сигурен в какъв формат Oracle ги очаква, но се надяваме, че ще бъде просто въпрос на предаване на низовете (r.get("c13")
ако дължината на пълното вмъкване е по-малка от 2000, f.substring(0,2000)
и f
ако създавате и актуализации) на помощна функция, за да направите това.
Ако е вероятно това преобразуване да увеличи размера на отпечатания ред, може да искате да намалите прага обратно до 1000, за да сте сигурни, за да сте сигурни, че преобразеният низ няма да доведе до ред, по-голям от ограничението PL/SQL.
Съжалявам, ако това изглежда объркано, но ограниченията, които посочихте, ни натоварват малко. Може да има по-добър начин, но не мога да се сетя за такъв, който да отговаря на всички вашите критерии.
Актуализация: Изглежда, че сте дори повече hamstring отколкото първоначално се смяташе:ако трябва да се ограничите до SQL за генериране скриптът, както и изпълнението му, има начин, макар и мъчителен.
Можете да използвате SQL за генериране на SQL. Използвайки моята по-горе спомената таблица с c1
и c13
, можете да направите:
select
'insert into newtable (c1,c13) values ("' ||
c1 ||
'","");'
from oldtable;
# Xlates to: insert into newtable (c1,c13) values ("[c1]","");
Това ще ви даде цялата ваша базова линия insert
изрази за дублиране на всичко освен c13
колона.
Това, което тогава трябва да направите, е да генерирате повече изрази за настройка на c13
. За да актуализирате c13
за всички стойности с дължина 1000 или по-малко (прост набор):
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
След това за update
c13 за всички стойности между 1001 и 2000 знака (задайте и след това добавете):
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.
И така нататък за тези, които са с дължина от 2001 до 3000 и от 3001 до 4000.
Вероятно ще трябва да се направят някои настройки. Радвам се да ви дам начин да го разрешите, но желанието ми да работя върху такова чудовище до завършване е минимално в най-добрия случай :-)
Ще свърши ли работата? да. красиво ли е? Бих казал, че това беше категорично "НЕ!" но предвид вашите ограничения, това може да е най-доброто, на което можете да се надявате.
Като доказателство за концепцията, ето един SQL скрипт в DB2 (но без специални функции, той трябва да работи добре във всяка СУБД, която има length
и substr
еквивалент):
# 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;
и това генерира следните редове:
> 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';
Разбивайки изходните редове, получаваме:
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';
което трябва да ви даде оригиналните редове, макар и по заобиколен начин.
И това е приблизително толкова усилие, колкото мога да положа във всеки един въпрос, без мозъкът ми да се пържи, така че ще ви кажа сбогом, освен ако не ми бъдат посочени сериозни грешки.
Успех с вашия проект и най-добри пожелания.