示例数据 - “执行包含更新和插入语句的存储过程时出现问题”

Posted

技术标签:

【中文标题】示例数据 - “执行包含更新和插入语句的存储过程时出现问题”【英文标题】:Sample data - "Issue while executing stored procedure which consists both update and insert statements" 【发布时间】:2017-05-18 20:13:22 【问题描述】:

以下是我在“执行包含更新和插入语句的存储过程时的问题”中提出的问题的示例表和文件详细信息。以下是我在执行程序之前要遵循的步骤。

    我将从供应商处获得一个文件,其中包含以下格式的数据。

    6437,,01/01/2017,3483.92,,
    14081,,01/01/2017,8444.23,,
    

    我正在将这些数据加载到表 NMAC_PTMS_NOTEBK_SG。在上述文件中,第一列将是资产。

    我正在使用与该资产相关的名称为 lse_id 的额外列更新表。现在NMAC_PTMS_NOTEBK_SG 表将包含以下格式的数据。

    LSE_ID  AST_ID PRPRTY_TAX_DDCTN_CD LIEN_DT    ASES_PRT_1_AM ASES_PRT_2_AM
    5868087 5049   Null                01-01-2017 3693.3        NULL
    

    现在我的程序将开始。在我的过程中,逻辑应该是我需要从NMAC_PTMS_NOTEBK_SG 中获取lse_id 并在MJL 表中进行比较(此处为lse_id = app_lse_s)。以下是MJL 表的结构。

    CREATE TABLE LPR_LP_TEST.MJL
    (
      APP_LSE_S     CHAR(10 BYTE)                   NOT NULL,
      DT_ENT_S      TIMESTAMP(3)                    NOT NULL, 
      DT_FOL_S      TIMESTAMP(3),
      NOTE_TYPE_S   CHAR(4 BYTE)                    NOT NULL,
      PRCS_C        CHAR(1 BYTE)                    NOT NULL,
      PRIO_C        CHAR(1 BYTE)                    NOT NULL,
      FROM_S        CHAR(3 BYTE)                    NOT NULL,
      TO_S          CHAR(3 BYTE)                    NOT NULL,
      NOTE_TITLE_S  VARCHAR2(41 BYTE)               NOT NULL,
      INFO_S        VARCHAR2(4000 BYTE),
      STAMP_L       NUMBER(10)                      NOT NULL,
      PRIVATE_C     CHAR(1 BYTE),
      LSE_ACC_C     CHAR(1 BYTE),
      COL_STAT_S    CHAR(4 BYTE),
      INFO1_S       VARCHAR2(250 BYTE),
      INFO2_S       VARCHAR2(250 BYTE),
      INFO3_S       VARCHAR2(250 BYTE),
      INFO4_S       VARCHAR2(250 BYTE),
      NTBK_RSN_S    CHAR(4 BYTE)
    )
    TABLESPACE LPR_LP_TEST
    PCTUSED    0
    PCTFREE    25
    INITRANS   1
    MAXTRANS   255
    STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
    )
    LOGGING 
    NOCOMPRESS 
    NOCACHE
    NOPARALLEL
    MONITORING;
    
    CREATE UNIQUE INDEX LPR_LP_TEST.MJL_IDX0 ON LPR_LP_TEST.MJL
    (APP_LSE_S, DT_ENT_S)
    LOGGING
    TABLESPACE LPR_LP_TEST
    PCTFREE    10
    INITRANS   2
    MAXTRANS   255
    STORAGE    (
        INITIAL          64K
        NEXT             1M
        MINEXTENTS       1
        MAXEXTENTS       UNLIMITED
        PCTINCREASE      0
        BUFFER_POOL      DEFAULT
    )
    NOPARALLEL;
    
    CREATE OR REPLACE TRIGGER LPR_LP_TEST."MT_MJL_AIUD" 
    AFTER INSERT OR UPDATE OR DELETE ON mjl
    BEGIN
    mpkg_trig_mjl.mp_mjl_aiud;
    END mt_mjl_aiud;
    / 
    
    CREATE OR REPLACE TRIGGER LPR_LP_TEST."MT_MJL_AIUDR" 
    AFTER INSERT OR UPDATE OR DELETE ON mjl FOR EACH ROW
    BEGIN
    mpkg_trig_mjl.mp_mjl_aiudr (INSERTING, UPDATING, DELETING,
                :NEW.app_lse_s, :NEW.prcs_c, :NEW.note_type_s,
                :OLD.app_lse_s, :OLD.prcs_c, :OLD.note_type_s);
    END mt_mjl_aiudr;
    /
    
    CREATE OR REPLACE TRIGGER LPR_LP_TEST."MT_MJL_BIUD" 
    BEFORE INSERT OR UPDATE OR DELETE ON mjl
    BEGIN
    mpkg_trig_mjl.mp_mjl_biud;
    END mt_mjl_biud;
    /
    
    CREATE OR REPLACE TRIGGER LPR_LP_TEST."MT_MJL_OBIUR" 
    BEFORE INSERT OR UPDATE ON mjl FOR EACH ROW
    BEGIN
    IF INSERTING THEN
        :NEW.stamp_l := mpkg_util.mp_time_ticker;
    ELSE
        IF :OLD.stamp_l > 999999990 THEN
            :NEW.stamp_l := 1;
        ELSE
            :NEW.stamp_l := :OLD.stamp_l + 1;
        END IF;
    END IF;
    END mt_mjl_obiur;
    /     
    

    以下是您在上一篇文章中提供的我正在使用的程序,它几乎对我有用。


CREATE OR REPLACE PROCEDURE LPR_LP_TEST.SP_PTMS_NOTES
      (
      p_app_lse_s     IN mjl.app_lse_s%TYPE,
      --p_dt_ent_s      IN mjl.dt_ent_s%TYPE,
      --p_note_type_s   IN mjl.note_type_s%TYPE,
      --p_prcs_c        IN mjl.prcs_c%TYPE,
      --p_prio_c        IN mjl.prio_c%TYPE,
      --p_note_title_s  IN mjl.note_title_s%TYPE,
      --p_info1_s       IN mjl.info1_s%TYPE,
      --p_info2_s       IN mjl.info2_s%TYPE
      )
      AS
      --v_rowcount_i   number;
      --v_lien_date    mjl.info1_s%TYPE;
      --v_lien_date    NMAC_PTMS_NOTEBK_SG.LIEN_DT%TYPE;
      --v_asst_amount  mjl.info2_s%TYPE;
      v_app_lse_s    mjl.app_lse_s%TYPE;
BEGIN
      v_app_lse_s := trim(p_app_lse_s);

      -- I hope this dbms_output line is for temporary debug purposes only
      -- and will be removed in the production version!
      dbms_output.put_line(app_lse_s);

      merge into mjl tgt
      using (select lse_s app_lse_s,
                    sysdate dt_ent_s,
                    'SPPT' note_type_s,
                    'Y' prcs_c,
                    '1' prio_c,
                    'Property Tax Assessment' note_title_s,
                    lien_dt info1_s,
                    ases_prt_1_am info2_s
             from   nmac_ptms_notebk_sg
             where  lse_id = v_app_lse_s) src
      on (trim(tgt.app_lse_s) = trim(src.app_lse_s))
        -- and tgt.dt_ent_s = src.dt_ent_s) 
      when matched then
      update set --tgt.dt_ent_s = src.dt_ent_s,
                 tgt.note_title_s = src.note_title_s,
                 tgt.info1_s = src.info1_s,
                 tgt.info2_s = src.info2_s
      where --tgt.dt_ent_s != src.dt_ent_s
         tgt.note_title_s != src.note_title_s
      or    tgt.info1_s != src.info1_s
      or    tgt.info2_s != src.info2_s
      when not matched then
      insert (tgt.app_lse_s,
              tgt.dt_ent_s,
              tgt.note_type_s,
              tgt.prcs_c,
              tgt.prio_c,
              tgt.from_s,
              tgt.to_s,
              tgt.note_title_s,
              tgt.info1_s,
              tgt.info2_s)
      values (src.app_lse_s,
              src.dt_ent_s,
              src.note_type_s,
              src.prcs_c,
              src.prio_c,
              src.from_s,
              src.to_s,
              src.note_title_s,
              src.info1_s,
              src.info2_s);

      commit;
end;
    现在逻辑应该是我需要从我的文件中传递lse_id 已保存到程序中。 如果我传递的 lse_idapp_lse_s 匹配 mjl 表然后我需要更新该行和一些硬编码 我正在做的字段是正确的。 如果lse_id 不匹配,那么我必须为此插入一个新行 租约和硬编码字段。 我面临的问题是dt_ent_s 表中的mjl 是一个 唯一约束。

如果以上对您有任何意义,请告诉我...

【问题讨论】:

你可以通过程序的格式代码编辑问题吗? @Nitish。我试图改变程序的格式代码。有点没有反映.... 【参考方案1】:

“我面临的问题是 mjl 表中的 dt_ent_s 是一个唯一约束。”

实际上不是,它是复合唯一键的一部分。所以真的你的 ON 子句应该匹配

on (tgt.app_lse_s  = src.app_lse_s
    and tgt.dt_ent_s = src.dt_ent_s)

顺便说一句,在 ON 子句中使用trim() 令人担忧,尤其是trim(tgt.app_lse_s)。如果您要插入带有尾随或前导空格的值,您的“唯一键”将在您修剪它们时产生多个命中。当您从文件加载数据并在表中插入修剪后的值时,您应该修剪空格。


“ORA-00001:违反了唯一约束 (LPR_LP_TEST.MJL_IDX0)”

MJL_IDX0 必须是唯一索引。这意味着您需要在考虑唯一记录时将其列包括在内。

很明显,您的直接 INSERT 逻辑和您的 MERGE INSERT 逻辑之间存在差异。您需要比较这两个语句并找出不同之处。

【讨论】:

我在这里又遇到了一个错误。插入时抛出 ORA-00001: 违反唯一约束 (LPR_LP_TEST.MJL_IDX0)。我检查了 MJL 表,并为此创建了一个索引。我的问题是,当我尝试使用正常的插入语句插入记录时,它起作用但在合并语句中不起作用。你能帮我解决这个问题吗? 现在我在执行此过程时遇到错误。你能检查一下这个吗。 03494 开始 SP_PTMS_NOTES('03494');结尾; * 第 1 行出现错误:ORA-30926:无法在源表中获得一组稳定的行 ORA-06512:在“LPR_LP_TEST.SP_PTMS_NOTES”,第 18 行 ORA-06512:在第 1 行 请阅读我对a question on ORA-30926 的回复。如果这不能帮助您解决问题,您将需要提出一个新问题,发布您的 MERGE 语句和一小组重现问题的示例数据。

以上是关于示例数据 - “执行包含更新和插入语句的存储过程时出现问题”的主要内容,如果未能解决你的问题,请参考以下文章

Vertica示例数据库安装

在混合表达式中创建示例数据

pyspider示例代码三:用PyQuery解析页面数据

R语言使用data函数获取当前R环境可用的示例数据集:获取datasets包中的所有示例数据集获取所有包的数据集获取特定包的数据集

Mysql示例数据库

数据类型示例 [重复]