Форум программистов, компьютерный форум, киберфорум
Oracle
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.54/13: Рейтинг темы: голосов - 13, средняя оценка - 4.54
23 / 12 / 2
Регистрация: 23.08.2010
Сообщений: 100
1

Заполнение таблицы по диапазону

30.03.2016, 09:44. Показов 2686. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!
Есть таблица:
Oracle 11 SQL
1
2
3
4
5
6
CREATE TABLE range_table
(
start_range NUMBER(10),
end_range NUMBER(10),
val_range NUMBER(10)
);
На начальном этапе у нас заполнены два поля: start_range и end_range.
В таблице такие поля могут быть заполнены несколько раз:
start_rangeend_rangeval_range
110000NULL
2541098398NULL
384623847548NULL
...

В итоге, необходимо заполнить в этой таблице поле val_range:
start_rangeend_rangeval_range
1 10000 1
1 10000 2
1 10000 3
1 10000 4
...  
1 10000 10000
254 1098398 254
254 1098398 255
254 1098398 256
254 1098398 257
...  
254 1098398 1098398
384623 847548 384623
384623 847548 384624
384623 847548 384625
384623 847548 384626
...  
384623 847548 847548

И это все сделать одним селектом, у меня есть два скрипта-примера:
SQL
1
2
3
4
5
6
SELECT   t.start_range
        ,t.end_range
        ,(t.start_range+(level-1)) val_range
    FROM range_table t
    WHERE t.val_range IS NULL
  CONNECT BY (level-1) <= (t.end_range-t.start_range)
SQL
1
2
3
4
5
6
WITH temp (start_range,end_range,val_range) AS
 (SELECT start_range,end_range,val_range FROM range_table t WHERE t.val_range IS NULL-- Initial Subquery
 UNION ALL
 SELECT start_range,end_range,val_range+1 FROM temp -- Recursive Subquery
 WHERE val_range < end_range)
SELECT start_range,end_range,val_range FROM temp
Они оба рабочие, но хотелось бы узнать, есть ли третий вариант как эту задачу решить, который будет более шустрый по сравнению с моими скриптами? А то если в сумме должно быть записей 8,5 млн., то они долго работают. Конечно понятное дело, что у меня рекурсия сделана и из-за этого работает долго.

Заранее спасибо за помощь!
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.03.2016, 09:44
Ответы с готовыми решениями:

Фильтрация таблицы по диапазону дат
Доброго времени суток, господа! Недавно начал изучать ASP.NET MVC и не могу разобраться как решить...

Фильтрация таблицы по диапазону дат
Есть таблица, которая заполняется данными с базы MySql, есть сортировка и фильтрация этой таблицы...

Автоматическое заполнение таблицы данными из другой таблицы при соблюдении определенного условия
Добрый день! Объяснить сложно, поэтому попробую на примере. По работе составляю графики...

Заполнение детальной таблицы, не имея мастер таблицы
Здравствуйте. Столкнулся при разработке со следующей проблемой. Пользователь нажимает кнопку...

7
763 / 664 / 194
Регистрация: 24.11.2015
Сообщений: 2,158
30.03.2016, 12:29 2
Вам надо заполнить по уже имеющимся записям, или создать набор записей?
Например, у Вас в таблице есть всего четыре строки
1 10000 null
1 10000 null
1 10000 null
1 10000 null
Вам надо сделать из них тоже четыре строки
1 10000 1
1 10000 2
1 10000 3
1 10000 4
или Вам надо создать дополнительно 10000-4 строк и все заполнить?
0
23 / 12 / 2
Регистрация: 23.08.2010
Сообщений: 100
30.03.2016, 14:48  [ТС] 3
надо создать дополнительно 10001 строку и заполнить столбец val_range одним селектом
Вот более наглядный пример, может он будет более конкретным, что мне надо
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
DECLARE
  v_i NUMBER(10);
BEGIN
  FOR v_gt IN (SELECT /*+ parallel(t 10)*/ t.start_range,t.end_range FROM range_table t WHERE t.val_range IS NULL)
    LOOP
      v_i:=0;
--Выводим сколько будет добавлено строк в таблицу
      dbms_output.put_line(v_gt.end_range||'-'||v_gt.start_range||'='||(v_gt.end_range-v_gt.start_range));
      LOOP
        INSERT INTO /*+ append */ range_table (start_range,end_range,val_range)
        VALUES (v_gt.start_range,v_gt.end_range,(v_gt.start_range+v_i));
--Через каждые 1000 строк делаем коммит
        IF MOD(v_i,1000)=0
          THEN
            commit;
          END IF;
        v_i:=v_i+1;
--Если мы дошли до границы диапазона, то выходим из цикла и берем следующую партию диапазонов
        EXIT WHEN (v_i+v_gt.start_range) > v_gt.end_range;
      END LOOP;
--еще раз делаем коммит
      commit;
    END LOOP;
--удаляем все строки, у которых поле val_range не заполнено
DELETE FROM range_table t WHERE t.val_range IS NULL;
commit;
END;
Этот цикл, кстати намного быстрее работает, чем мои вышенаписанные, но задача такая, чтобы обойтись без pl/sql
0
763 / 664 / 194
Регистрация: 24.11.2015
Сообщений: 2,158
30.03.2016, 15:06 4
Мне Ваш последний скрипт нравится гораздо больше селектов. Я как раз хотел предложить написать что-то подобное. Других вариантов я не придумал, разве что использовать pipeline-функции. Если не знаете, почитайте. Вы даете функции два значения, она Вам выкидывает набор строк.
Могу поделиться некоторым печальным опытом. Не знаю как на Вашей базе, а на моей, если CONNECT BY level <n и n>2000000 (приблизительно), то селект начинает работать, а потом валится с невиданной ранее ошибкой "Недостаточно ресурсов". Pipeline-функции тоже съедают много ресурсов, поэтому и с ними возможно подобное (правда лично не наблюдал).
1
23 / 12 / 2
Регистрация: 23.08.2010
Сообщений: 100
30.03.2016, 15:17  [ТС] 5
Да мне этот цикл тоже нравится больше, но к сожалению его нельзя использовать.
Вот у меня так же с CONNECT BY level: работает-работет, а потом выдает ошибку (типа конец файла, в итоге то, что сессия оборвана) и все, дальше не идет.
спасибо за pipeline, попробую прикрутить к своей задаче.

Добавлено через 6 минут
кстати, скрипт
SQL
1
2
3
4
5
6
WITH temp (start_range,end_range,val_range) AS
 (SELECT start_range,end_range,val_range FROM range_table t WHERE t.val_range IS NULL-- Initial Subquery
 UNION ALL
 SELECT start_range,end_range,val_range+1 FROM temp -- Recursive Subquery
 WHERE val_range < end_range)
SELECT start_range,end_range,val_range FROM temp
более или менее работает, вставляет данные, но объем > 8 млн. строк вставляет более суток
0
763 / 664 / 194
Регистрация: 24.11.2015
Сообщений: 2,158
30.03.2016, 15:28 6
Цитата Сообщение от olejik Посмотреть сообщение
но к сожалению его нельзя использовать
Нельзя потому что задание такое? Или какая-то другая причина?
0
23 / 12 / 2
Регистрация: 23.08.2010
Сообщений: 100
30.03.2016, 16:13  [ТС] 7
Я думал, что нельзя, а оказалось можно.
Все дело в том, что этот алгоритм должен работать в Informatica Power Center. Там есть трансформация SQL, куда код вставляется и выполнятется этот скрипт, для апдейтов и инсертов актуально, но как только я туда цикл вставил - он мне сказал, что ошибка, а оказалось, что надо было этот скрипт засунуть в другую трансформацию, экранировать символы ; и тогда будет работать и оно работает! )))
0
763 / 664 / 194
Регистрация: 24.11.2015
Сообщений: 2,158
30.03.2016, 17:30 8
Цитата Сообщение от olejik Посмотреть сообщение
Я думал, что нельзя, а оказалось можно
Ну и замечательно. Бывают такие редкие случаи когда (квази)процедура работает быстрее чистого селекта. Кстати, не факт, что в Вашей системе сработал бы pipline. Так что все решилось ко всеобщему удовольствию.
0
30.03.2016, 17:30
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
30.03.2016, 17:30
Помогаю со студенческими работами здесь

Автоматическое заполнение таблицы данными из другой таблицы
Добрый день. Возникла проблема с Экселем. Требуется на листе Production автоматически вставить...

Заполнение таблицы данными из другой таблицы
Нужно сделать запрос на заполнение пустой колонки в таблице1 из таблицы2, есть общее поле . Один...

Заполнение таблицы по данным из другой таблицы
Добрый день! Помогите пожалуйста написать формулу для заполнение таблицы. Необходимо из таблице...

БД "Тестирование пользователей". Заполнение таблицы данными из формы и другой таблицы
Идея данной БД - тестирование пользователей. Есть три таблицы: Пользователь ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru