Действителен ли следующий код? Я получаю ошибки. - PullRequest
0 голосов
/ 23 марта 2011
CREATE OR REPLACE VIEW POINTS AS
DECLARE
  avgDurationOurFault       number(5);
  avgDurationCustomersFault number(5);
  avgDuration           number(5);

BEGIN

    (select ceil(avg(abs(total_time))) into avgDuration from inquiry);

    select ceil(avg(total_duration))  into avgDurationOurFault
    from
    (
        select customer_no, sum(abs(total_time)) total_duration
        from inquiry
        where cat_id in ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909')
        GROUP BY customer_no);

    select ceil(avg(total_duration))  into avgDurationCustomersFault
    from
    (
        select customer_no, sum(abs(total_time)) total_duration
        from inquiry
        where cat_id in ('C903','C904', 'C906')
        group by customer_no);

    select t1.customer_no, t1.callPoints, t1.durationPoints, t2.catgPoints, 
          t1.callPoints+t1.durationPoints+t2.catgPoints as totalPoints
    from 
    (
        select customer_no, count(inquiry_id)*avgDuration callPoints , sum(abs(total_time)) durationPoints
        from inquiry 
        group by customer_no
        ) t1

        inner join (

        select customer_no, sum(points) catgPoints
        from
        (
        select customer_no,
            case
                when cat_id in ('C903','C904', 'C906')
                then 0

            when cat_id in ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909')
                then 2*avgDuration + abs(avgDurationCustomersFault - avgDurationOurFault)

            else
                0

            end as points
            from inquiry
            )
            group by customer_no
            ) t2

            on t1.customer_no = t2.customer_no;


END;
/

-------------------- ОШИБКИ НИЖЕ ------------------------- --------------------------

Ошибка запуска в строке 1 в команде: СОЗДАТЬ ИЛИ ЗАМЕНИТЬ ТОЧКИ ЗРЕНИЯ КАК ОБЪЯВИТЬ номер avgDurationOurFault (5) Ошибка в командной строке: 1 Колонка: 32 Отчет об ошибке: Ошибка SQL: ORA-00928: отсутствует ключевое слово SELECT 00928. 00000 - «отсутствует ключевое слово SELECT» * Причина:
* Действие:

Ошибка запуска в строке 4 в команде: avgDurationCustomersFault number (5) Отчет об ошибке: неизвестная команда

Ошибка запуска в строке 5 в команде: avgDuration number (5) Ошибка отчет: неизвестная команда

Ошибка запуска в строке 7 в команде:

BEGIN

(select ceil(avg(abs(total_time))) into avgDuration from inquiry);

select ceil(avg(total_duration))  into avgDurationOurFault
from
(
    select customer_no, sum(abs(total_time)) total_duration
    from inquiry
    where cat_id in ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909')
    GROUP BY customer_no);

select ceil(avg(total_duration))  into avgDurationCustomersFault
from
(
    select customer_no, sum(abs(total_time)) total_duration
    from inquiry
    where cat_id in ('C903','C904', 'C906')
    group by customer_no);
select t1.customer_no, t1.callPoints, t1.durationPoints, t2.catgPoints, 
      t1.callPoints+t1.durationPoints+t2.catgPoints as totalPoints
from 
(
    select customer_no, count(inquiry_id)*avgDuration callPoints , sum(abs(total_time)) durationPoints
    from inquiry 
    group by customer_no
    ) t1

    inner join (
    select customer_no, sum(points) catgPoints
    from
    (
    select customer_no,
        case
            when cat_id in ('C903','C904', 'C906')
            then 0

        when cat_id in ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909')
            then 2*avgDuration + abs(avgDurationCustomersFault - avgDurationOurFault)
        else
            0

        end as points
        from inquiry
        )
        group by customer_no
        ) t2

        on t1.customer_no = t2.customer_no;

END;

Отчет об ошибке: ORA-06550: строка 3, столбец 2: PLS-00103: обнаружен символ "(", когда ожидается одно из следующего:

начинать регистр объявлять выход для goto if loop mod null pragma Повышение Возврат выберите обновление, а с << закрыть текущее удаление извлекать блокировку вставить открытую откат forall merge pipe Символ «обновление» был заменен на «(» для продолжения. ORA-06550: строка 3, столбец 37: PLS-00103: Обнаружен символ «INTO» при ожидании одного из следующее: </p>

. (, *% & - + / в мод rem, начиная с || Символ ". был вставлен перед "I ORA-06550: строка 3, столбец 67: PLS-00103: Натолкнулся на символ ";" при ожидании одного из следующих действий:

комплект ORA-06550: строка 30, столбец 3: PLS-00103: обнаружен символ «ВНУТРЕННИЙ» при ожидании одного из следующих действий:

,; для группы, имеющей пересечение минус порядок, начало объединения, где
соединять 06550. 00000 - «строка% s, столбец% s: \ n% s» * Причина: обычно ошибка компиляции PL / SQL. * Действие:

Ответы [ 2 ]

4 голосов
/ 23 марта 2011

Использование:

CREATE OR REPLACE VIEW POINTS AS
SELECT a.customer_no, 
       a.callPoints, 
       a.durationPoints,
       a.catgPoints, 
       a.callPoints + a.durationPoints + a.catgPoints as totalPoints
  FROM (SELECT i.customer_no, 
               COUNT(i.inquiry_id) * x.avgDuration AS callPoints, 
               SUM(ABS(i.total_time)) durationPoints,
               SUM(CASE
                     WHEN i.cat_id IN ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909') THEN 
                       2 * x.avgDuration + ABS(z.avgDurationCustomersFault - y.avgDurationOurFault)
                     ELSE 0
                   END) AS catgpoints
          FROM INQUIRY i
    CROSS JOIN (SELECT CEIL(AVG(ABS(t.total_time))) AS avgDuration 
                  FROM INQUIRY t) x
    CROSS JOIN (SELECT CEIL(AVG(total_duration)) AS avgDurationOurFault
                  FROM (SELECT SUM(ABS(t.total_time)) AS total_duration
                          FROM INQUIRY t
                         WHERE t.cat_id IN ('C900', 'C901', 'C902', 'C905', 'C907', 'C908', 'C909')
                      GROUP BY t.customer_no) y
    CROSS JOIN (SELECT CEIL(AVG(total_duration)) AS avgDurationCustomersFault
                  FROM (SELECT SUM(ABS(t.total_time)) AS total_duration
                          FROM INQUIRY
                         WHERE t.cat_id IN ('C903','C904', 'C906')
                      GROUP BY t.customer_no) z
      GROUP BY i.customer_no) a

Можно объединить "y" и "z", используя оператор CASE для суммирования значений в соответствии с cat_id.Кто-то еще может играть в гольф с этим.

Проблема с вашим запросом заключается в том, что вы пытались использовать несколько несвязанных операторов SELECT.Представление - это отдельный оператор SELECT - вы можете использовать подзапросы, производные таблицы / встроенные представления и т. Д., Но они должны находиться внутри одного запроса, как вы видите в моем примере.То, что вы опубликовали, больше похоже на то, что вы найдете в хранимой процедуре или функции.Вы не можете использовать переменные, например, как вы пытались, и вам не нужно - просто нужен CROSS JOIN.

Факторинг подзапроса (AKA WITH, CTE) можно использовать, ноКак правило, выигрыш в производительности практически отсутствует.

4 голосов
/ 23 марта 2011

Представление не может использовать PL / SQL таким образом.Вы должны собрать все свои запросы вместе.Что-то вроде CREATE OR REPLACE VIEW POINTS AS [one huge sql statement...].

...