как вставить данные в таблицу фактов с помощью процедуры - PullRequest
0 голосов
/ 15 января 2019

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

Я пытался написать этот запрос, но он не работал.

CREATE OR REPLACE PROCEDURE final_upload_fact AS
  CURSOR finally IS
    SELECT p.clean_project_key,
         u.cconsultant_key,
         c.stage_company_key,
         t.time_key
    FROM   clean_project p
    INNER  JOIN clean_consultant u
    ON     p.clean_consultant_id = u.cldmch_id
    INNER  JOIN clean_company c
    ON     p.clean_company_id = c.stage_ldmch_id
    INNER  JOIN dim_time t
    ON     t.year = to_char(p.clean_estimated_end_date, 'yyyy')
    OR     t.year = to_char(p.clean_actual_end_date, 'yyyy');
BEGIN
  FOR k IN finally
  LOOP
    INSERT INTO fact
    (prjfinished_estimatedate,
     hig_qual_consultant,
     nooffeedbackless3,
     noprjoverrunmnth,
     fk1_dim_consultant_key,
     fk2_time_key,
     fk3_dim_project_key,
     fk4_dim_company_key)
    VALUES
    (SELECT COUNT(dim_project_key)
     FROM   dim_project
     WHERE  dim_project_estimated_end_date <= dim_actual_end_date, 
       SELECT MAX(dim_highest_quality)
     FROM   dim_consultant,
       SELECT COUNT(dim_feedbackvalue)
       FROM   dim_project
       WHERE  dim_feedbackvalue != 'N/A'
       AND    dim_feedbackvalue <= 3,  SELECT COUNT(dim_project_key)
               FROM   dim_project,
       k.cconsultant_key,
       k.time_key,
       k.clean_project_key,
       k.stage_company_key);
  END LOOP;
END;
/

1 Ответ

0 голосов
/ 15 января 2019

Проблема заключается в том, что в вашем подзапросе нет скобок в предложении VALUES.

Когда вы ссылаетесь на подзапросы, вам нужно заключить их в квадратные скобки, чтобы ваш код выглядел следующим образом:

CREATE OR REPLACE PROCEDURE final_upload_fact AS
  CURSOR finally IS
    SELECT p.clean_project_key,
           u.cconsultant_key,
           c.stage_company_key,
           t.time_key
    FROM   clean_project p
    INNER  JOIN clean_consultant u
    ON     p.clean_consultant_id = u.cldmch_id
    INNER  JOIN clean_company c
    ON     p.clean_company_id = c.stage_ldmch_id
    INNER  JOIN dim_time t
    ON     t.year = to_char(p.clean_estimated_end_date, 'yyyy')
    OR     t.year = to_char(p.clean_actual_end_date, 'yyyy');
BEGIN
  FOR k IN finally
  LOOP
    INSERT INTO fact
      (prjfinished_estimatedate,
       hig_qual_consultant,
       nooffeedbackless3,
       noprjoverrunmnth,
       fk1_dim_consultant_key,
       fk2_time_key,
       fk3_dim_project_key,
       fk4_dim_company_key)
    VALUES
      ((SELECT COUNT(dim_project_key)
        FROM   dim_project
        WHERE  dim_project_estimated_end_date <= dim_actual_end_date), 
       (SELECT MAX(dim_highest_quality)
        FROM   dim_consultant),
       (SELECT COUNT(dim_feedbackvalue)
        FROM   dim_project
        WHERE  dim_feedbackvalue != 'N/A'
        AND    dim_feedbackvalue <= 3),
       (SELECT COUNT(dim_project_key)
        FROM   dim_project),
       k.cconsultant_key,
       k.time_key,
       k.clean_project_key,
       k.stage_company_key);
  END LOOP;
END;
/

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

Предполагая, что ваши подзапросы не имеют никакой корреляции с курсором, который вы определили, вы можете переписать все это так:

CREATE OR REPLACE PROCEDURE final_upload_fact AS
    INSERT INTO fact
          (prjfinished_estimatedate,
           hig_qual_consultant,
           nooffeedbackless3,
           noprjoverrunmnth,
           fk1_dim_consultant_key,
           fk2_time_key,
           fk3_dim_project_key,
           fk4_dim_company_key)
    SELECT (SELECT COUNT(dim_project_key)
            FROM   dim_project
            WHERE  dim_project_estimated_end_date <= dim_actual_end_date) cnt_est_less_act_end_dt, 
           (SELECT MAX(dim_highest_quality)
            FROM   dim_consultant) max_highest_quality_consultant,
           (SELECT COUNT(dim_feedbackvalue)
            FROM   dim_project
            WHERE  dim_feedbackvalue != 'N/A'
            AND    dim_feedbackvalue <= 3) feedback_cnt,
           (SELECT COUNT(dim_project_key)
            FROM   dim_project) project_cnt,
           p.clean_project_key,
           u.cconsultant_key,
           c.stage_company_key,
           t.time_key
    FROM   clean_project p
    INNER  JOIN clean_consultant u
    ON     p.clean_consultant_id = u.cldmch_id
    INNER  JOIN clean_company c
    ON     p.clean_company_id = c.stage_ldmch_id
    INNER  JOIN dim_time t
    ON     t.year = to_char(p.clean_estimated_end_date, 'yyyy')
    OR     t.year = to_char(p.clean_actual_end_date, 'yyyy');
END final_upload_fact;
/

Таким образом, вы удаляете все переключения контекста между PL / SQL и SQL, которые есть в вашей исходной процедуре (т. Е. Открываете курсор в PL / SQL, переключаетесь на SQL, чтобы сгенерировать план выполнения, назад на PL / SQL, чтобы запросить следующая строка, обратно в SQL, чтобы получить следующую строку, обратно в PL / SQL, чтобы сохранить строку в записи, обратно в SQL, чтобы вставить соответствующие данные, обратно в PL / SQL, чтобы определить, достигнут ли конец цикла, и поэтому запросить следующую строку и т. д. и т. д.).

...