示例数据 - “执行包含更新和插入语句的存储过程时出现问题”
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_id
与 app_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 语句和一小组重现问题的示例数据。以上是关于示例数据 - “执行包含更新和插入语句的存储过程时出现问题”的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用data函数获取当前R环境可用的示例数据集:获取datasets包中的所有示例数据集获取所有包的数据集获取特定包的数据集