我尝试使用过程将数据从其他维表插入事实表,但无法执行。有时它会显示缺少的表达式,有时会忽略错误语句。
我通过编写此查询进行了尝试,但没有成功。
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;
/
答案 0 :(得分:2)
问题是您的子查询在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;
/
但是,可以通过将子查询移到游标中来极大地简化代码,这将消除遍历游标的需要,因为您可以执行insert-as-select。
假设子查询与定义的游标确实没有任何关联,则可以像这样重写整个内容:
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以确定循环的结束因此要求下一行,等等,等等。