2013-11-21 3 views
0

вот мой серийный table.it имеет более 1000 records.its с начальным номером и номером end.but между числами не существует. мне нужно добавить все количество [START/между & конечными номерами] записями в другом темпе таблица номера по номеру , как показано нижеКак получить число в диапазоне номеров PL-Sql.?

EXIST ТАБЛИЦЕ

select concat(CARD_BULK_CODE,start_serial) startserial,concat(CARD_BULK_CODE,end_serial) endserial 
from TSR_BULK_CARD_SERIALS 
 
--------------------------- 
STARTSERIAL ENDSERIAL | 
--------------------------- 
18126944 18126946 | 
18141101 18141122 | 
15150722 15150729 | 
19069303 19069317 | 
--------------------------- 

REQUIRED TABLE

 
----------- 
SERIAL_NO | 
----------- 
18126944  
18126945  
18141101  
18141102  
.... 
----------- 

Кажется, что это нужно pl-sql для реализации этого. , пожалуйста, помогите мне разобраться в этом выпуске

Я попытался с нижеследующим запросом с помощью dual. но очень медленно и пока не получили результаты :-) работает более чем 1 час

select distinct concat(t.CARD_BULK_CODE,t.START_SERIAL)+level-1 SERIAL 
from TSR_BULK_CARD_SERIALS t, dual 
connect by level-1<=(concat(t.CARD_BULK_CODE,t.END_SERIAL))-concat(t.CARD_BULK_CODE,t.START_SERIAL) 
order by 1 

EDIT:

Дорогой Ален & Dba.i пытались с них и ниже ошибка.

DECLARE 
    l_st NUMBER; 
    l_en NUMBER; 
BEGIN 
    FOR rec IN (select concat(card_bulk_code, start_serial) startserial,concat(card_bulk_code, end_serial) endserial from tsr_bulk_card_serials) 
    LOOP 
      l_st := rec.startserial; 
      l_en := rec.endserial; 
      FOR rec1 IN l_st..l_en 
      LOOP 
       INSERT INTO temp(serial_no) values(rec1); 
      END LOOP; 
    END LOOP; 
    COMMIT; 
END; 
Error at line 1 
ORA-01426: numeric overflow 
ORA-06512: at line 9 

Script Terminated on line 1. 
+1

Возможный дубликат [Oracle получить номера с диапазоном] (http://stackoverflow.com/questions/20045045/oracle-get-numbers-with-range) –

+1

опубликовать структуру таблицы temp для разрешения ошибки переполнения номера – psaraj12

+0

дорогой psaraj12, \t его с serial_no column | тип номер –

ответ

1

Просто напишите некоторые PL/SQL - итерацию через таблицу и вставлять строки в таблицу temp.

declare 
    l_start number; 
    l_end number; 
begin 
    for r_rec in (select to_number(concat(card_bulk_code, start_serial)) startserial 
       ,  to_number(concat(card_bulk_code, end_serial)) endserial 
       from tsr_bulk_card_serials) 
    loop 
     l_start := r_rec.startserial; 
     l_end := r_rec.endserial; 
     for l_i in l_start..l_end loop 
     insert into your_temp_table; 
     end loop; 
    end loop; 
end; 
+0

Дорогой друг Ален. Вопрос обновлен –

+0

Просто добавьте to_number (...), чтобы тип данных был числовым. Функция Concat в вашем примере, вероятно, возвращает тип varchar2. Обновленный ответ. –

+1

Насколько велики ваши цифры? Что такое max starterial и enderial? –

1

Попробуйте, как это,

WITH t(ST, EN) AS 
(
    SELECT 18126944, 18126946 FROM dual 
    UNION 
    SELECT 18141101, 18141122 FROM dual 
    UNION 
    SELECT 15150722, 15150729 FROM dual 
    UNION 
    SELECT 19069303 , 19069317 FROM dual 
) 
SELECT DISTINCT st + LEVEL -1 
FROM t 
CONNECT BY LEVEL <= (SELECT en - st + 1 FROM DUAL) 
ORDER BY 1; 

/

Попробуйте что-нибудь подобное для PL/SQL,

DECLARE 
    l_st NUMBER; 
    l_en NUMBER; 
BEGIN 
    FOR rec IN (SELECT * FROM t) 
    LOOP 
      l_st := rec.st; 
      l_en := rec.en; 
      FOR rec1 IN l_st..l_en 
      LOOP 
       INSERT INTO <your_tab>; 
      END LOOP; 
    END LOOP; 
    COMMIT; 
END;  
+0

дорогой Дба, а как насчет pl-sql для использования здесь? потому что больше строк в таблице существует –

+3

Это производит огромное количество строк и будет медленным. –

+2

Просто напишите PL/SQL - итетерируйте свою таблицу и вставьте строки в таблицу temp. –

4

Один из способов сделать это, не прибегая к PLSQL

WITH ranges AS 
(
    SELECT CONCAT(CARD_BULK_CODE, start_serial) startserial, 
     CONCAT(CARD_BULK_CODE, end_serial) endserial 
    FROM TSR_BULK_CARD_SERIALS 
), 
numbers(n) AS (
    SELECT 0 n 
    FROM dual 
UNION ALL 
    SELECT n + 1 
    FROM numbers 
    WHERE n <= 
    (
    SELECT MAX(endserial - startserial) 
     FROM ranges 
) 
) 
SELECT t.startserial + n.n SERIAL_NO 
    FROM ranges t JOIN numbers n 
    ON n.n <= t.endserial - t.startserial 
ORDER BY SERIAL_NO 

Вот SQLFiddle демо

+0

спасибо дорогой peterm.I был судим один раз с dual.but его получить больше времени для выполнения.thatswhy я прошу plsql :-) –

0
DECLARE 
    l_st  NUMBER (20); 
    l_en  NUMBER (20); 
    testnum NUMBER (4); 
BEGIN 
    FOR rec IN (SELECT CONCAT (card_bulk_code, start_serial) startserial,CONCAT (card_bulk_code, end_serial) endserial FROM tsr_bulk_card_serials) 
    LOOP 
     l_st := TO_NUMBER (rec.startserial); 
     l_en := TO_NUMBER (rec.endserial); 
     testnum := l_en - l_st; 
     DBMS_OUTPUT.put_line (l_st); 
     DBMS_OUTPUT.put_line (l_en); 

     IF l_st < l_en 
     THEN 
     FOR rec1 IN 0 .. testnum 
     LOOP 
      l_st := l_st + 1; 

      INSERT INTO temp(serial_no) VALUES (l_st); 
     END LOOP; 
     END IF; 
    END LOOP; 
    COMMIT; 
END; 

выше код помог мне отсортирован мой вопрос спасибо всем :-)

Смежные вопросы