【发布时间】:2019-01-22 22:38:06
【问题描述】:
我有一个要使用 SQL 更新的数据库表。基本上,它带有一组时间表小册子部分的描述信息,但这并不重要。一些数据已经通过应用程序输入,但它很耗时,而且其中的一部分是“样板”,需要每周更新。在某些情况下,我可能错过了通过应用程序输入数据,因此如果数据不存在,我也想自动创建数据。
这导致我使用 MERGE 查询,如下所示:
MERGE INTO TTP_LINE_DESCRIPTION o
USING
(SELECT DISTINCT lv.lv_nv_id TLDE_NV_ID,
lv.lv_id TLDE_LV_ID,
dir.dir_id TLDE_DIR_ID,
8 TLDE_MED_FLAG,
1 TLDE_TYPE,
0 TLDE_SORT_NO,
'Timetable valid from ' || to_char(lv.lv_valid_from,'DD/MM/YYYY') || ' until ' || nvl2(lv.lv_valid_until,to_char(lv.lv_valid_until,'DD/MM/YYYY'),'further notice') TLDE_TEXT,
0 TLDE_ALIGNMENT,
null TLDE_FONT_SIZE,
null TLDE_FONT_STYLE
FROM LINE_VERSION lv
JOIN line_point_sequence lps ON (lv.lv_id = lps.lps_lv_id)
JOIN direction dir ON (dir.dir_id = lps.lps_dir_id)
where lv.lv_nv_id=3799 and lv.lv_id=10455244) n
ON (o.TLDE_NV_ID=n.TLDE_NV_ID
and o.TLDE_LV_ID=n.TLDE_LV_ID
and o.TLDE_DIR_ID=n.TLDE_DIR_ID
and o.TLDE_TYPE=n.TLDE_TYPE
and o.TLDE_SORT_NO=n.TLDE_SORT_NO)
WHEN MATCHED THEN
UPDATE SET o.TLDE_TEXT=n.TLDE_TEXT,
o.TLDE_ALIGNMENT=n.TLDE_ALIGNMENT,
o.TLDE_FONT_SIZE=n.TLDE_FONT_SIZE,
o.TLDE_FONT_STYLE=n.TLDE_FONT_STYLE
WHEN NOT MATCHED THEN
INSERT (o.tlde_id, o.tlde_nv_id, o.tlde_lv_id, o.tlde_dir_id,
o.tlde_med_flag, o.tlde_type, o.tlde_sort_no, o.tlde_text,
o.tlde_alignment, o.tlde_font_size, o.tlde_font_style,
o.updated_by, o.updated_on, o.updated_prog)
VALUES ((select max(tld.tlde_id)+1 from TTP_LINE_DESCRIPTION tld),
n.tlde_nv_id, n.tlde_lv_id, n.tlde_dir_id, n.tlde_med_flag,
n.tlde_type, n.tlde_sort_no, n.tlde_text, n.tlde_alignment,
n.tlde_font_size, n.tlde_font_style, 'STUARTR',
SYSDATE, 'PL/SQL Developer');
这里有一点需要注意,就是SELECT DISTINCT 中的WHERE 子句。 lv.lv_id=10455244 是一个引用,我知道它将强制选择只返回该 SELECT 中的一对行,这样我就可以限制我的测试。为此,10455244 是当前不在 TTP_LINE_DESCRIPTION 表中的有效值。
当我使用表中的值时,WHEN MATCHED 代码正确执行,并在 0.016 秒内更新一对行。
使用我上面显示的值自行运行 SELECT 语句会返回需要添加 0.109 秒的两行。
根据最后 VALUES 行中的第一项获取最大 id 并向其添加一个(这是主键)需要 0s。
最后,如果我写一个 INSERT INTO 并显式写下我想为其中一行写的所有值,我可以在 0.016 秒内完成一行的 INSERT。
但是把它们放在一起,然后……什么都没有。执行只是坐在那里,执行,并且似乎没有结束。或者我很紧张,等着看它是否会结束。我已经离开了一段合理的时间,但似乎没有任何东西进入。
那么发生了什么事,为什么它不做我认为它应该做的事?
【问题讨论】:
-
您是否:检查计划,您是否计划/时间:选择 * TTP_LINE_DESCRIPTION o 内部连接 (SELECT DISTINCT ... ) n ON (o.TLDE_NV_ID=n.TLDE_NV_ID 和 o.TLDE_LV_ID=n. TLDE_LV_ID 和 o.TLDE_DIR_ID=n.TLDE_DIR_ID 和 o.TLDE_TYPE=n.TLDE_TYPE 和 o.TLDE_SORT_NO=n.TLDE_SORT_NO)
-
不,但是现在这样做需要 0.016 秒才能返回 0 行(因为我正在检查 NOT MATCHED 条件),或者如果我删除了我知道不存在的 lv_id,我会返回0.905 秒内 1049 行,都不是特别慢。
-
另外,为什么这个问题被否决了?我对很多 SQL 还是陌生的,所以我可能在做一些愚蠢的事情,这个问题可以得到回答,我已经通过分解和测试不同的部分来证明我一直在尝试不同的方法来让我的代码工作。