2013-04-12 49 views
0

我有兩個插入語句,如下面的A和B.我需要將這兩個插入語句合併爲一個,如語句C.我不喜歡重複的代碼,例如語句A和B中的選擇部分。什麼是正確的格式對於陳述C?請忽略動態查詢語句,因爲真實語句選擇部分非常複雜。如何在Oracle中使用插入語句插入到兩個表中?

聲明答:

insert into a 
    (firstname, lastname) 
    select t2.firstname, t3.lastname 
    from t1, t2, t3 
    where t1.t1_id = t2.t1_id 
    and t2.t2_id = t3.t2_id; 

聲明B:

insert into b 
    (personid) 
    select t1.personid 
    from t1, t2, t3 
    where t1.t1_id = t2.t1_id 
    and t2.t2_id = t3.t2_id; 

聲明C:

insert into a 
    (firstname, lastname) 
insert into b 
    (personid) 
    select t2.firstname, t3.lastname, t1.personid 
    from t1, t2, t3 
    where t1.t1_id = t2.t1_id 
    and t2.t2_id = t3.t2_id; 

現實世界最初的說法是象下面這樣:

procedure allo_recipient(p_all_id  number, 
         p_allo_type varchar2, 
         p_step_no  number, 
         p_region  varchar2, 
         p_don_reg_code varchar2, 
         p_med_urgent varchar2, 
         p_don_id  number, 
         p_abo_ic  varchar2, 
         p_multi_organ varchar2) is 
begin 
    insert into all_pat_list 
    (apl_id, 
    all_id, 
    prod_id, 
    prior_seq_no, 
    org_code, 
    all_step_no, 
    pat_id, 
    pat_name, 
    sex, 
    dob, 
    ped_ind, 
    blood_typ, 
    home_prov_code, 
    home_town, 
    org_code_registered, 
    org_descrip_registered, 
    hosp_id, 
    mrn, 
    oldr_code, 
    current_wait_list_stat_code, 
    init_wait_list_stat_date, 
    dis_code_prim_diag, 
    dis_code_sec_diag, 
    cadaver_liv_ind, 
    weight, 
    height, 
    abdom_girth, 
    chest_circum, 
    chest_vert_right, 
    chest_vert_left, 
    chest_transverse, 
    cmv, 
    ebv, 
    hepatitis_b_surface_ant, 
    hepatitis_c, 
    prev_trnsplt_no, 
    all_step_descrip, 
    eff_date, 
    hcv_rna, 
    dsa_cur_unaccp1, 
    dsa_acc_unaccp1, 
    dsa_cur_indet1, 
    dsa_acc_indet1, 
    dsa_cur_unaccp2, 
    dsa_acc_unaccp2, 
    dsa_cur_indet2, 
    dsa_acc_indet2, 
    x_match_serum_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    x_match_b_cell_res_ind, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    x_match_t_cell_res_ind, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    current_pra, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    current_pra_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    peak_pra, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    peak_pra_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    kp_allocation_points, 
    cpra) --to do: c_pra need be replaced with new one in furture. 
    --3rd select: get all needed elements for all_pat_list 
    select apl_seq.nextval apl_id, 
      p_all_id all_id, 
      prod_id, 
      all_kp_prior_seq.nextval prior_seq_no, 
      org_code, 
      all_step_no, 
      pat_id, 
      pat_name, 
      sex, 
      dob, 
      ped_ind, 
      blood_typ, 
      home_prov_code, 
      home_town, 
      org_code_registered, 
      tttt_gen_pkg.get_org_type_desc(org_code_registered) org_descrip_registered, 
      hosp_id, 
      mrn, 
      tttt_gen_pkg.get_hosp_oldr_code(hosp_id) oldr_code, 
      current_wait_list_stat_code, 
      list_date init_wait_list_stat_date, 
      dis_code_prim_diag, 
      dis_code_sec_diag, 
      cadaver_liv_ind, 
      tttt_gen_pkg.get_latest_pat_weight(pat_id) weight, 
      tttt_gen_pkg.get_latest_pat_height(pat_id) height, 
      tttt_gen_pkg.get_latest_pat_abdom_girth(pat_id) abdom_girth, 
      tttt_gen_pkg.get_latest_pat_chest_circum(pat_id) chest_circum, 
      tttt_gen_pkg.get_latest_pat_chest_vr(pat_id) chest_vert_right, 
      tttt_gen_pkg.get_latest_pat_chest_vl(pat_id) chest_vert_left, 
      tttt_gen_pkg.get_latest_pat_chest_trans(pat_id) chest_transverse, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'CMV') cmv, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'EBV') ebv, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HBSAG') hepatitis_b_surface_ant, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HCV') hepatitis_c, 
      tttt_gen_pkg.get_prev_tx_count(pat_id, org_code) prev_trnsplt_no, --tttt_gen_pkg.get_prev_tx_count(pat_id, 1) prev_trnsplt_no, 
      tttt_gen_pkg.get_all_step_descrip(p_step_no, org_code) all_step_descrip, --tttt_gen_pkg.get_all_step_descrip(p_step_no, 1) all_step_descrip, 
      sysdate, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HCV_RNA') hcv_rna, 
      null dsa_cur_unaccp1, 
      null dsa_acc_unaccp1, 
      null dsa_cur_indet1, 
      null dsa_acc_indet1, 
      null dsa_cur_unaccp2, 
      null dsa_acc_unaccp2, 
      null dsa_cur_indet2, 
      null dsa_acc_indet2, 
      null x_match_serum_date, 
      null x_match_b_cell_res_ind, 
      null x_match_t_cell_res_ind, 
      null current_pra, 
      null current_pra_date, 
      null peak_pra, 
      null peak_pra_date, 
      kp_allocation_points, 
      cpra 
     from (
      -- 1st select: get basic elements of pat list for each step 
      select distinct prod.org_code, 
          p_step_no all_step_no, 
          p.pat_id, 
          p.last_name || ', ' || p.first_name || ' ' || 
          p.middle_name pat_name, 
          p.sex, 
          p.dob, 
          decode(sign(months_between(sysdate, p.dob)/12 - 18), -1, 'P', 'A') ped_ind, 
          p.blood_typ, 
          pr.prov_code_home home_prov_code, 
          pr.home_town, 
          pr.org_code org_code_registered, 
          pr.hosp_id, 
          pr.mrn, 
          tttt_gen_pkg.get_current_wls_code(prod_id) current_wait_list_stat_code, 
          tttt_gen_pkg.get_initial_wls_date(prod.prod_id) list_date, --init_wait_list_stat_date 
          dis_code_prim_diag, 
          dis_code_sec_diag, 
          cadaver_liv_ind, 
          pr.patr_id, 
          prod.prod_id, 
          tttt_kp_allocation.allocation_points(pr.patr_id, prod.org_code) kp_allocation_points, 
          null cpra 
       from pat p, temp_kp_pat_pool pr, pat_register_org_det prod 
      where p.pat_id = pr.pat_id 
       and pr.patr_id = prod.patr_id 
       and (p_allo_type, prod.org_code) in 
        (('K', '3'), ('K', '6'), ('P', '6')) -- ('K' => K; K/P; P) ('P' => K/P; P) 

       and (pr.patr_id not in 
        (select patr_id from temp_kp_used_patrid_pool)) -- filter out patr_id(s) which has been handled in previous steps 

       and pr.cadaver_liv_ind in ('B', 'D') --waiting for deceased and both. 

       and (((p_region = 'L') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON') and 
        (tttt_gen_pkg.get_hosp_oldr_code(pr.hosp_id) = 
        p_don_reg_code)) or 

        ((p_region = 'O') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON') and 
        (tttt_gen_pkg.get_hosp_oldr_code(pr.hosp_id) != 
        p_don_reg_code)) or 

        ((p_region = 'P') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON')) or 

        --((p_region = 'H') and 
        --(tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) != 'ON') and 
        --(tttt_gen_pkg.is_hsp_pat = 'Y')) or -- to do: need pat HSP flag to identify pat belongs to HSP 

        ((p_region = 'NA') and (1 = 1))) 

       and (((p_med_urgent = 'Y') and 
        (tttt_gen_pkg.get_current_wls_code(prod.prod_id) = 'H')) or 

        ((p_med_urgent = 'NA') and (1 = 1))) 

       and (((p_abo_ic = 'PI') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'PI')) or 

        ((p_abo_ic = 'I') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'I')) or 

        ((p_abo_ic = 'C') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'C')) or 

        ((p_abo_ic = 'NA') and (1 = 1))) 

       and (((p_multi_organ = 'Y') and 
        (pr.org_code in (10, 14, 15))) or 

        ((p_multi_organ = 'NA') and (1 = 1))) 

      order by kp_allocation_points desc, cpra desc, list_date -- end of 1st select 
      ); --end of 2rd select 

的實際使用修改聲明「埃德吉布斯」的解決方案是像下面,但不幸的是我得到了編譯錯誤:

「封裝集合體tttt.tttt_KP_ALLOCATION編譯錯誤

錯誤:PL/SQL:ORA- 02287:序列號這裏不允許 線:636 文字:all_kp_prior_seq.nextval prior_seq_no,

錯誤:PL/SQL:SQL語句忽略 線:574 文本:插入所有進入all_pat_list值

錯誤:提示:參數'p_loc_pro已說明,但在 'run_kp_allo' 行從未使用過:847 文字:p_loc_pro VARCHAR2, 「

procedure allo_recipient(p_all_id  number, 
         p_allo_type varchar2, 
         p_step_no  number, 
         p_region  varchar2, 
         p_don_reg_code varchar2, 
         p_med_urgent varchar2, 
         p_don_id  number, 
         p_abo_ic  varchar2, 
         p_multi_organ varchar2) is 
begin 
    insert all into all_pat_list values 
    (apl_id, 
    all_id, 
    prod_id, 
    prior_seq_no, 
    org_code, 
    all_step_no, 
    pat_id, 
    pat_name, 
    sex, 
    dob, 
    ped_ind, 
    blood_typ, 
    home_prov_code, 
    home_town, 
    org_code_registered, 
    org_descrip_registered, 
    hosp_id, 
    mrn, 
    oldr_code, 
    current_wait_list_stat_code, 
    init_wait_list_stat_date, 
    dis_code_prim_diag, 
    dis_code_sec_diag, 
    cadaver_liv_ind, 
    weight, 
    height, 
    abdom_girth, 
    chest_circum, 
    chest_vert_right, 
    chest_vert_left, 
    chest_transverse, 
    cmv, 
    ebv, 
    hepatitis_b_surface_ant, 
    hepatitis_c, 
    prev_trnsplt_no, 
    all_step_descrip, 
    eff_date, 
    hcv_rna, 
    dsa_cur_unaccp1, 
    dsa_acc_unaccp1, 
    dsa_cur_indet1, 
    dsa_acc_indet1, 
    dsa_cur_unaccp2, 
    dsa_acc_unaccp2, 
    dsa_cur_indet2, 
    dsa_acc_indet2, 
    x_match_serum_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    x_match_b_cell_res_ind, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    x_match_t_cell_res_ind, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    current_pra, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    current_pra_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    peak_pra, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    peak_pra_date, -- to do: this field is use by old allocation report, it need determine keep or discard in the new report 
    kp_allocation_points, 
    cpra) --to do: c_pra need be replaced with new one in furture. 
    into temp_kp_used_patrid_pool values (patr_id) 
    --3rd select: get all needed elements for all_pat_list 
    select apl_seq.nextval apl_id, 
      p_all_id all_id, 
      prod_id, 
      all_kp_prior_seq.nextval prior_seq_no, 
      org_code, 
      all_step_no, 
      pat_id, 
      pat_name, 
      sex, 
      dob, 
      ped_ind, 
      blood_typ, 
      home_prov_code, 
      home_town, 
      org_code_registered, 
      tttt_gen_pkg.get_org_type_desc(org_code_registered) org_descrip_registered, 
      hosp_id, 
      mrn, 
      tttt_gen_pkg.get_hosp_oldr_code(hosp_id) oldr_code, 
      current_wait_list_stat_code, 
      list_date init_wait_list_stat_date, 
      dis_code_prim_diag, 
      dis_code_sec_diag, 
      cadaver_liv_ind, 
      tttt_gen_pkg.get_latest_pat_weight(pat_id) weight, 
      tttt_gen_pkg.get_latest_pat_height(pat_id) height, 
      tttt_gen_pkg.get_latest_pat_abdom_girth(pat_id) abdom_girth, 
      tttt_gen_pkg.get_latest_pat_chest_circum(pat_id) chest_circum, 
      tttt_gen_pkg.get_latest_pat_chest_vr(pat_id) chest_vert_right, 
      tttt_gen_pkg.get_latest_pat_chest_vl(pat_id) chest_vert_left, 
      tttt_gen_pkg.get_latest_pat_chest_trans(pat_id) chest_transverse, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'CMV') cmv, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'EBV') ebv, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HBSAG') hepatitis_b_surface_ant, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HCV') hepatitis_c, 
      tttt_gen_pkg.get_prev_tx_count(pat_id, org_code) prev_trnsplt_no, --tttt_gen_pkg.get_prev_tx_count(pat_id, 1) prev_trnsplt_no, 
      tttt_gen_pkg.get_all_step_descrip(p_step_no, org_code) all_step_descrip, --tttt_gen_pkg.get_all_step_descrip(p_step_no, 1) all_step_descrip, 
      sysdate, 
      tttt_gen_pkg.get_latest_test_res(pat_id, 'HCV_RNA') hcv_rna, 
      null dsa_cur_unaccp1, 
      null dsa_acc_unaccp1, 
      null dsa_cur_indet1, 
      null dsa_acc_indet1, 
      null dsa_cur_unaccp2, 
      null dsa_acc_unaccp2, 
      null dsa_cur_indet2, 
      null dsa_acc_indet2, 
      null x_match_serum_date, 
      null x_match_b_cell_res_ind, 
      null x_match_t_cell_res_ind, 
      null current_pra, 
      null current_pra_date, 
      null peak_pra, 
      null peak_pra_date, 
      kp_allocation_points, 
      cpra, 
      patr_id 
     from (
      -- 1st select: get basic elements of pat list for each step 
      select distinct prod.org_code, 
          p_step_no all_step_no, 
          p.pat_id, 
          p.last_name || ', ' || p.first_name || ' ' || 
          p.middle_name pat_name, 
          p.sex, 
          p.dob, 
          decode(sign(months_between(sysdate, p.dob)/12 - 18), -1, 'P', 'A') ped_ind, 
          p.blood_typ, 
          pr.prov_code_home home_prov_code, 
          pr.home_town, 
          pr.org_code org_code_registered, 
          pr.hosp_id, 
          pr.mrn, 
          tttt_gen_pkg.get_current_wls_code(prod_id) current_wait_list_stat_code, 
          tttt_gen_pkg.get_initial_wls_date(prod.prod_id) list_date, --init_wait_list_stat_date 
          dis_code_prim_diag, 
          dis_code_sec_diag, 
          cadaver_liv_ind, 
          pr.patr_id, 
          prod.prod_id, 
          tttt_kp_allocation.allocation_points(pr.patr_id, prod.org_code) kp_allocation_points, 
          null cpra 
       from pat p, temp_kp_pat_pool pr, pat_register_org_det prod 
      where p.pat_id = pr.pat_id 
       and pr.patr_id = prod.patr_id 
       and (p_allo_type, prod.org_code) in 
        (('K', '3'), ('K', '6'), ('P', '6')) -- ('K' => K; K/P; P) ('P' => K/P; P) 

       and (pr.patr_id not in 
        (select patr_id from temp_kp_used_patrid_pool)) -- filter out patr_id(s) which has been handled in previous steps 

       and pr.cadaver_liv_ind in ('B', 'D') --waiting for deceased and both. 

       and (((p_region = 'L') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON') and 
        (tttt_gen_pkg.get_hosp_oldr_code(pr.hosp_id) = 
        p_don_reg_code)) or 

        ((p_region = 'O') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON') and 
        (tttt_gen_pkg.get_hosp_oldr_code(pr.hosp_id) != 
        p_don_reg_code)) or 

        ((p_region = 'P') and 
        (tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) = 'ON')) or 

        --((p_region = 'H') and 
        --(tttt_gen_pkg.get_hosp_prov_code(pr.hosp_id) != 'ON') and 
        --(tttt_gen_pkg.is_hsp_pat = 'Y')) or -- to do: need pat HSP flag to identify pat belongs to HSP 

        ((p_region = 'NA') and (1 = 1))) 

       and (((p_med_urgent = 'Y') and 
        (tttt_gen_pkg.get_current_wls_code(prod.prod_id) = 'H')) or 

        ((p_med_urgent = 'NA') and (1 = 1))) 

       and (((p_abo_ic = 'PI') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'PI')) or 

        ((p_abo_ic = 'I') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'I')) or 

        ((p_abo_ic = 'C') and 
        (tttt_kp_allocation.kp_abo_c_i(p_don_id, pr.pat_id) = 'C')) or 

        ((p_abo_ic = 'NA') and (1 = 1))) 

       and (((p_multi_organ = 'Y') and 
        (pr.org_code in (10, 14, 15))) or 

        ((p_multi_organ = 'NA') and (1 = 1))) 

      order by kp_allocation_points desc, cpra desc, list_date -- end of 1st select 
      ); --end of 2rd select 
+1

你可以使用'INSERT語句ALL' – Sebas

回答

6

正如Sebas上面說的,INSERT ALL就是答案。您的「語句A」和「聲明B」與INSERT ALL合併應該是這樣的:

INSERT ALL 
    INTO a VALUES (firstname, lastname) 
    INTO b VALUES (personid) 
select t2.firstname, t3.lastname, t1.personid 
    from t1, t2, t3 
where t1.t1_id = t2.t1_id 
    and t2.t2_id = t3.t2_id 

此外,作爲HLGEM指出,隱含的連接被普遍不贊成時下。以下是如何與ANSI風格加入做到這一點:

INSERT ALL 
    INTO a VALUES (firstname, lastname) 
    INTO b VALUES (personid) 
SELECT t2.firstname, t3.lastname, t1.personid 
FROM t1 
INNER JOIN t2 ON t1.t1_id = t2.t1_id 
INNER JOIN t3 ON t2.t2_id = t3.t2_id 
+0

不鼓勵使用隱式的加入SQL反模式的。 – HLGEM

+0

@HLGEM - 你說得對。我總是在自己的代碼中使用ANSI連接,但是當我回答問題時,我傾向於離開連接,就像他們在OP的例子中一樣。我會編輯迴應。 –

+0

@HLGEM - 進行了修改,謝謝。我明白你的觀點 - 隱式聯接接近我的「不喜歡」列表的頂部(緊隨其後的是粗糙的別名) - 但請注意,我的原始答案確實完成了OP想要做的事情。 –