Ух ты, эти ограничения довольно ограничивающие, но я думаю, что есть способ обойти это. Я думаю, вам, возможно, придется написать свой собственный маленький сценарий для этого.
Я бы сам использовал 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 .
Извините, если это кажется запутанным, но ограничения, которые вы указали, немного мешают нам. Возможно, есть лучший способ, но я не могу придумать тот, который соответствует всем вашим критериям.
Обновление: Похоже, вы даже больше подколены, чем первоначально предполагалось: если вам нужно ограничить себя 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';
, который должен дать вам исходные строки, хотя и окольным путем.
И это примерно столько же усилий, сколько я могу поставить на любой вопрос, не напрягая мозги, поэтому я попрошу вас, если на меня не укажут какие-либо серьезные ошибки.
Удачи в вашем проекте и наилучших пожеланий.