【问题标题】:using execute immediate to insert into使用立即执行插入
【发布时间】:2017-05-17 14:18:47
【问题描述】:

在程序之外似乎可以正常工作,但在程序内部时它似乎没有做任何事情。该过程符合并无错误地运行,但不插入任何行。谁能帮帮我,拜托。

create or replace procedure sp_retail_transaction_insert 
authid current_user
as
begin
  execute immediate ('
  insert into sp_retail_transaction 
  (indiv_id, perm_id, acct_type, acct_source, tender_cd, trans_header_id, trans_datetime_full,
  trans_type, tot_price_amt, promotion_code, store_name, store_type, store_cat, store_terminal_location, store_area_location, cmp_period, staff)
  select 
  a.indiv_id, 
  a.perm_id,
  a.acct_type,
  a.acct_source,
  a.tender_cd,
  a.trans_header_id,
  a.trans_datetime_full,
  a.trans_type,
  a.tot_price_amt,
  a.promotion_code,
  a.company_name as store_name,
  a.site_type as store_type,
  a.secondary_site_type as store_cat,
  a.airport_terminal as store_terminal_location,
  a.building_desc as store_area_location,
  case when 
  trans_datetime_full between to_date(b.start_date, ''dd/mm/yyyy'') 
  and 
  to_date (b.end_date, ''dd/mm/yyyy'') then ''cmp_period''
  when to_date(trans_datetime_full, ''dd/mm/yyyy'')<to_date(b.start_date, ''dd/mm/yyyy'') then ''pre_cmp_period''
  when to_date(trans_datetime_full, ''dd/mm/yyyy'')>to_date(b.end_date, ''dd/mm/yyyy'') then ''post_cmp_period''
  end as cmp_period,
  case when c.staff_flag = 1 or c.staff_flag_revised = 1 or c.pseudo_staff_flag = 1 then 1 else 0 end as staff
  from sp_temp b, tableau.an_retail_trans_full a 
  left join tableau.an_individual_tb_full  c
  on a.indiv_id=c.indiv_id
  where a.tot_price_amt>0 and 
  a.indiv_id is not null and

      (   instr ('','' || upper(b.airport_terminal)|| '','', '','' ||upper(a.airport_terminal)|| '','') <> 0 or upper(b.airport_terminal) is null) and 
          (   instr ('','' || upper(b.store_name) || '','', '','' || upper(a.loc_desc_long) || '','') <> 0 or upper(b.store_name) is null) and 
          (   instr ('','' || upper(b.acct_type) || '','' , '','' || upper(a.acct_type) || '','') <> 0 or upper(b.acct_type) is null) and
          (   instr ('','' || upper(b.trans_type) || '','', '','' || upper(a.trans_type) || '','') <> 0 or upper(b.trans_type) is null) 
  and
  a.trans_datetime_full between (to_date(b.start_date,''dd/mm/yyyy'')-( to_date (b.end_date,''dd/mm/yyyy'') - to_date(b.start_date,''dd/mm/yyyy''))) 
  and 
  (to_date (b.end_date,''dd/mm/yyyy'')+( to_date (b.end_date, ''dd/mm/yyyy'') - to_date(b.start_date, ''dd/mm/yyyy'')))');
end sp_retail_transaction_insert;

【问题讨论】:

  • 为什么要使用动态 SQL?
  • 别忘了提交。
  • 我正在使用 SQL Developer 进行编码。
  • 是的,但是您在此处发布的代码中没有任何内容证明使用动态 SQL 是合理的。
  • 是的,这就是 INSERT INTO ... SELECT FROM 所做的。这不需要动态 SQL。只需将 SQL 放入过程中即可。我们只需要在有条件地更改 SQL 时使用动态 SQL,例如根据一些输入参数改变目标表

标签: oracle plsql dynamic-sql


【解决方案1】:

如果执行插入的会话中没有提交问题,则在发出提交之前,其他会话将无法使用记录。如果会话在提交之前退出,那么记录会回滚。

【讨论】:

    【解决方案2】:

    答案:用逗号分隔

    create or replace PROCEDURE CA_RETAIL_TRANSACTION_INSERT   AUTHID CURRENT_USER   AS
    BEGIN
    INSERT INTO CA_RETAIL_TRANSACTION   SELECT A.INDIV_ID, 
    A.PERM_ID,
      A.ACCT_TYPE,
        A.ACCT_SOURCE,
          A.TENDER_CD,
            A.TRANS_HEADER_ID,
              A.TRANS_DATETIME_FULL,
                A.TRANS_TYPE,
                  A.TOT_PRICE_AMT,
                    A.PROMOTION_CODE,
                      A.COMPANY_NAME AS STORE_NAME,
                        A.SITE_TYPE AS STORE_TYPE,
                          A.SECONDARY_SITE_TYPE AS STORE_CAT,
                            A.AIRPORT_TERMINAL AS STORE_TERMINAL_LOCATION,
                              A.BUILDING_DESC AS STORE_AREA_LOCATION,
    
                            CASE WHEN 
                          TRANS_DATETIME_FULL 
    
                      BETWEEN B.START_DATE 
                    AND B.END_DATE 
                  THEN 'CMP_PERIOD'
    
                WHEN TRANS_DATETIME_FULL < 
              B.START_DATE 
            THEN 'PRE_CMP_PERIOD'
    
         WHEN 
        TRANS_DATETIME_FULL> 
      B.END_DATE
     THEN 'POST_CMP_PERIOD'
    END AS CMP_PERIOD,
    
    CASE when 
      C.Staff_Flag = 1 OR 
        C.Staff_Flag_Revised = 1 OR 
          C.Pseudo_Staff_Flag = 1 
            then 1 else 0 
    END AS Staff
    
    FROM TABLEAU.AN_RETAIL_TRANS_FULL A
    
      JOIN 
        CA_TEMP B
          ON 
          A.TRANS_DATETIME_FULL BETWEEN
        B.PRE_START_DATE AND
          B.POST_END_DATE 
    
    
      left JOIN
        TABLEAU.AN_INDIVIDUAL_TB_FULL C
          ON
          A.INDIV_ID = C.INDIV_ID
    
    WHERE 
      A.TRANS_DATETIME_FULL BETWEEN
        B.PRE_START_DATE AND
          B.POST_END_DATE AND
    
    A.TOT_PRICE_AMT > 0 AND
          A.INDIV_ID IS NOT NULL  AND
    
        (   INSTR (',' || UPPER(B.AIRPORT_TERMINAL)|| ',', 
                   ',' || UPPER(A.AIRPORT_TERMINAL)|| ',') <> 0 OR 
                          UPPER(B.AIRPORT_TERMINAL) IS NULL) AND 
    
            (   INSTR (',' || UPPER(B.STORE_NAME) || ',', 
                       ',' || UPPER(A.COMPANY_NAME) || ',') <> 0 OR 
                              UPPER(B.STORE_NAME) IS NULL) AND 
    
                (   INSTR (',' || UPPER(B.ACCT_TYPE) || ',' , 
                           ',' || UPPER(A.ACCT_TYPE) || ',') <> 0 OR 
                                   UPPER(B.ACCT_TYPE) IS NULL) AND
    
                    (   INSTR (',' || UPPER(B.TRANS_TYPE) || ',', 
                               ',' || UPPER(A.TRANS_TYPE) || ',') <> 0 OR 
                                      UPPER(B.TRANS_TYPE) IS NULL) ;
    

    结束 CA_RETAIL_TRANSACTION_INSERT;

    【讨论】: