2012-02-27 5 views
0

Я использую Oracle 11g и написал хранимую процедуру, которая сохраняет значения во временной таблице следующим образом:реф курсор с динамическими столбцами

id count hour age range 
------------------------------------- 
0  5  10  61  10-200 
1  6  20  61  10-200 
2  7  15  61  10-200 
5  9  5  61  201-300 
7  10  25  61  201-300 
0  5  10  62  10-20 
1  6  20  62  10-20 
2  7  15  62  10-20 
5  9  5  62  21-30 
1  8  6  62  21-30 
7  10  25  62  21-30 
10  15  30  62  31-40 

теперь использует эту временную таблицу я хочу вернуть два курсора. один для 61 и один для 62 (возраст). , а для курсоров - различные диапазоны. например, курсор в возрасте 62 лет должен возвращаться в качестве набора данных.

user  10-20  21-30  31-40 
     Count/hour count/hour count/hour 
---------------------------------------------- 
0   5  10  - -  - -  
1   6  20  8 6  - -  
2   7  15  - -  - -  
5   -  -  9 5  - -   
7   -  -  10 25  - -  
10  -  -  - -  15 30   

Этот диапазон столбцов в таблице temp не является фиксированным значением, на которое они ссылаются из другой таблицы.

отредактировано: я использую PIVOT для проблемы выше, все примеры, которые я видел в Интернете, существуют для фиксированных значений столбцов (диапазон в моем случае). как я могу получить динамические значения. Ниже приведен запрос примера:

SELECT * 
FROM (SELECT column_2, column_1 
    FROM test_table) 
PIVOT (SUM(column1) AS sum_values FOR (column_2) IN ('value1' AS a, 'value2' AS b, 'value3' AS c)); 

Вместо того, чтобы использовать рукописное значение я использую следующий запрос внутри «IN»

SELECT * from(
with x as (
    SELECT DISTINCT range 
      FROM test_table 
     WHERE age = 62) 
select ltrim(max(sys_connect_by_path(range, ',')) 
       keep (dense_rank last order by curr), 
       ',') range 
    from (select range, 
       row_number() over (order by range) as curr, 
       row_number() over (order by range) -1 as prev 
      from x) 
connect by prev = PRIOR curr 
    start with curr = 1) 

он дает ошибку в этом случае. Но когда я использую рукописные значения, они дают правильный вывод.

select * from (select user_id, nvl(count,0) count, nvl(hour,0) hour,nvl(range,0) range,nvl(age,0) 
age from test_table) 
    PIVOT (SUM(count) as sum_count, sum(hour) as sum_hour for (range) IN 
(

'10-20','21-30','31-40' 
) 
) where age = 62 order by userid 

Как я могу динамически давать значения? как я могу это сделать.

ответ

2

Курсоры медленные, я бы рекомендовал попробовать сделать это в запросе, если нет альтернативы (или скорость не имеет значения). Вы можете посмотреть: PIVOT/UNPIVOT, который может вращать столбцы (в данном случае «диапазон»).

Вот некоторые PIVOT/UNPIVOT документация и примеры:
http://www.oracle-developer.net/display.php?id=506

На основе последнего редактирования:

Довольно уверен, у вас есть два варианта:

  1. Создание динамических sql на основе отдельных значений, найденных в столбце «диапазон».

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

  2. У Oracle есть команда PIVOT XML, которую вы можете использовать для этого.

    См: http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html

    и прокрутите вниз до раздела: "Тип XML"

+0

спасибо за ответ. Я использую его в asp .net. и данные меньше. поэтому скорость не должна быть проблемой. Я пытаюсь PIVOT теперь, я думаю, что он должен работать. – Pramod

+0

@Pramod Я добавил несколько дополнительных заметок. – Timeout

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