我已经编写了一个存储过程来使用join从三个不同的表中提取数据,但是我无法得到结果。我还尝试传递动态表但是发生了错误。
CREATE OR REPLACE Procedure DE_DUP_PRO1 (Dy_File_Name in varchar2)
--RETURN NUMBER
AS
v_hol varchar2(300);
CURSOR De_DUB_CUR IS
SELECT S.TRANS_GUID AS OLD_TRANS_GUID,
H.TRANS_GUID AS NEW_TRANS_GUID,
CASE
WHEN H.TRANS_GUID IS NULL
THEN 0
ELSE 1
END as TRN_STAT,
P.INTR_PHARMACY_ID, S.EXTRNL_PHARMACY_ID, S.PHARMACY_NM, S.PHARMACY_ADDR, S.SUPPLIERS_PSCR_DRUG_CD, S.PSCR_DRUG_IPU_CD,
'IPU', S.PSCR_DRUG_DESC, S.DSPNSD_DRUG_PACK_SIZE, S.RX_ID, S.RX_ITEM_SEQ, S.RX_REPEAT_STATUS, S.RX_TYP, S.EXMT_STATUS,
S.PSCR_QTY, S.NRSG_HM_IND, S.RX_DSPNSD_DT, S.RX_DSPNSD_TM, S.SUPPLIERS_DSPNSD_DRUG_CD, S.DSPNSD_DRUG_IPU_CD, 'IPU',
S.DSPNSD_DRUG_DESC, S.GENERIC_USE_MARKER, S.DSPNSD_UNIT_OF_QTY, S.DSPNSD_QTY, 'EUR', S.COST_OF_DSPNSD_QTY, S.VERBOSE_DOSAGE
FROM (SELECT stg.*, row_number() over ( partition BY key_clmns_hash ORDER BY 1 ) AS RN FROM T_MCL_30404_20150317_020 stg ) s
LEFT JOIN ps_pharmacy p ON s.extrnl_pharmacy_id = p.extrnl_pharmacy_id LEFT JOIN ps_rx_hist H ON h.key_clmns_hash = s.key_clmnS_hash
AND h.rx_dspnsd_dt = s.rx_dspnsd_dt AND s.supplier_pharmacy_cd = h.SUPPLIER_PHARMACY_CD AND s.detl_clmns_hash <> h.detl_clmns_hash WHERE S.RN = 1;
BEGIN
FOR De_Dub_rec IN De_DUB_CUR
LOOP
DBMS_OUTPUT.PUT_LINE ( De_Dub_rec.OLD_TRANS_GUID || '|' || De_Dub_rec.NEW_TRANS_GUID || '|' || De_Dub_rec.TRN_STAT || '|' || De_Dub_rec.P.INTR_PHARMACY_ID || '|' || De_Dub_rec.S.EXTRNL_PHARMACY_ID
|| '|' || De_Dub_rec.S.PHARMACY_NM || '|' || De_Dub_rec.S.PHARMACY_ADDR || '|' || De_Dub_rec.S.SUPPLIERS_PSCR_DRUG_CD|| '|' || De_Dub_rec.S.PSCR_DRUG_IPU_CD || '|' || 'IPU'
|| '|' || De_Dub_rec.S.PSCR_DRUG_DESC || '|' || De_Dub_rec.S.DSPNSD_DRUG_PACK_SIZE || '|' || De_Dub_rec.S.RX_ID || '|' || De_Dub_rec.S.RX_ITEM_SEQ || '|' || De_Dub_rec.S.RX_REPEAT_STATUS
|| '|' || De_Dub_rec.S.RX_TYP || '|' || De_Dub_rec.S.EXMT_STATUS || '|' || De_Dub_rec.S.PSCR_QTY || '|' || De_Dub_rec.S.NRSG_HM_IND || '|' || De_Dub_rec.S.RX_DSPNSD_DT
|| '|' || De_Dub_rec.S.RX_DSPNSD_TM || '|' || De_Dub_rec.S.SUPPLIERS_DSPNSD_DRUG_CD || '|' || De_Dub_rec.S.DSPNSD_DRUG_IPU_CD || '|' || 'IPU' || '|' || De_Dub_rec.S.DSPNSD_DRUG_DESC
|| '|' || De_Dub_rec.S.GENERIC_USE_MARKER || '|' || De_Dub_rec.S.DSPNSD_UNIT_OF_QTY || '|' || De_Dub_rec.S.DSPNSD_QTY || '|' || 'EUR' || '|' || De_Dub_rec.S.COST_OF_DSPNSD_QTY
|| '|'|| De_Dub_rec.S.VERBOSE_DOSAGE );
END LOOP;
-- RETURN 0;
END DE_DUP_PRO1;
/
每当我执行存储过程时,我都会遇到错误
LINE/COL ERROR
-------- -----------------------------------------------------------------
7/3 PL/SQL: SQL Statement ignored
19/96 PL/SQL: ORA-00942: table or view does not exist
31/9 PL/SQL: Statement ignored
31/32 PLS-00364: loop index variable 'DE_DUB_REC' use is invalid
LINE/COL ERROR(Now it is resolved)
-------- -----------------------------------------------------------------
28/7 PL/SQL: Statement ignored
28/7 PLS-00402: alias required in SELECT list of cursor to avoid
duplicate column names
答案 0 :(得分:0)
根据我的理解,下面的代码行由于列歧义而产生错误。
SELECT stg.*, row_number() over ( partition BY key_clmns_hash ORDER BY 1
只需在上面的行中明确提及带有别名的列名,而不是使用stg。*这将解决您的问题
答案 1 :(得分:0)
您的问题是您的查询正在选择一些文字字符串值而不设置任何别名:
select ..., 'IPU', ... , 'IPU', ..., 'EUR', ...
在上面的例子中,Oracle将自动生成丑陋的别名,如下所示:
select ..., 'IPU' AS "'IPU'", ..., 'IPU' AS "'IPU'", ..., 'EUR' AS "'EUR'", ...
正如你所看到的,你现在有3个非常难看的列名,这些名称很难处理,其中2个是重复的,导致你得到的错误。
考虑给它们适当的不同别名以避免歧义。这只是一个示例,但您应根据值的含义给出更有意义的别名:
select ..., 'IPU' AS some_col_1, ..., 'IPU' AS some_col_2, ..., 'EUR' AS some_col_3, ...
有趣的是,当您在游标中循环查询时,您 不 当前正在使用这3个值。在读取/循环光标时,您只需在打印时再次对值进行硬编码,而不是尝试从光标中读取3个值。
所以实际上,如果你真的不关心从光标读取3个值,只需将它们从查询中删除即可。否则,请使用您设置的别名替换DBMS_OUTPUT.PUT_LINE(...)
中的硬编码值。
因此,一旦您的查询得到修复,而不是:
DBMS_OUTPUT.PUT_LINE(... || 'IPU' || ... || 'IPU' || ... || 'EUR' || ...);
您应该像这样使用光标:
DBMS_OUTPUT.PUT_LINE(... || De_Dub_rec.some_col_1 || ... || De_Dub_rec.some_col_2 || ... || De_Dub_rec.some_col_3 || ...);