Oracle 别这样
如果你有像这样的更新Oracle 别这样,oracle,plsql,sql-update,oracle12c,database-performance,Oracle,Plsql,Sql Update,Oracle12c,Database Performance,如果你有像这样的更新 UPDATE MAIN_TBL MT SET MT.STOP_FLAG = ( SELECT CASE WHEN {whatever condition} THEN 'SF01' ELSE MT.STOP_FLAG END FROM DUAL ) UPDATE MAIN_TBL MT SET MT.STOP_FLAG = ( SELE
UPDATE MAIN_TBL MT
SET MT.STOP_FLAG = (
SELECT
CASE
WHEN {whatever condition}
THEN 'SF01'
ELSE MT.STOP_FLAG
END
FROM DUAL
)
UPDATE MAIN_TBL MT
SET MT.STOP_FLAG = (
SELECT
CASE
WHEN {whatever condition}
THEN 'SF01'
ELSE MT.STOP_FLAG
END
FROM DUAL
)
那基本上是一样的
UPDATE MAIN_TBL MT
SET MT.STOP_FLAG = 'SF01'
WHERE {whatever condition}
下面的示例很可能不是一个有效的解决方案,但它们应该给您一个提示,说明如何更好地编写此类更新
UPDATE MAIN_TBL MT
SET
MT.STOP_FLAG = 'SF01',
MT.ES = 'E',
MT.PW = 'W'
MT.UPDATE_DT = SYSDATE
WHERE
MT.STOP_FLAG IS NULL
AND MT.IDX_2 = 'G'
AND MT.ES IS NULL
AND MT.SS = 'C'
AND MT.PW = 'A'
AND NOT EXISTS (
SELECT 1
FROM LARGE_TBL LT
WHERE LT.LT_ID = MT.MT_ID
AND (LT.IDX_2 = 'G' OR LT.COL_1 <> 'Y' OR LT.COL_1 IS NULL)
);
UPDATE
(SELECT MT.*
FROM MAIN_TBL MT
JOIN LARGE_TBL LT ON LT.LT_ID = MT.MT_ID
WHERE LT.IDX_2 = 'G' OR LT.COL_1 <> 'Y' OR LT.COL_1 IS NULL)
SET
MT.STOP_FLAG = 'SF01',
MT.ES = 'E',
MT.PW = 'W'
MT.UPDATE_DT = SYSDATE
WHERE
MT.STOP_FLAG IS NULL
AND MT.IDX_2 = 'G'
AND MT.ES IS NULL
AND MT.SS = 'C'
AND MT.PW = 'A'
那么基本上跟
UPDATE MAIN_TBL MT
SET MT.STOP_FLAG = 'SF01'
WHERE {whatever condition}
您的条件可以有效地重新写入为检查lt.col_1字段的值是否不等于“Y”(即
lt.col_1为null或lt.col_1!=“Y”
)。我已经构建了一个快速测试用例,使用您的旧检查方法和新的:
WITH t1 AS (SELECT 1 mt_id, 10 val FROM dual UNION ALL
SELECT 2 mt_id, 20 val FROM dual UNION ALL
SELECT 3 mt_id, 30 val FROM dual UNION ALL
SELECT 4 mt_id, 40 val FROM dual UNION ALL
SELECT 5 mt_id, 50 val FROM dual),
t2 AS (SELECT 2 lt_id, 'F' idx_2, NULL col_1 FROM dual UNION ALL
SELECT 3 lt_id, 'G' idx_2, NULL col_1 FROM dual UNION ALL
SELECT 4 lt_id, 'G' idx_2, 'N' col_1 FROM dual UNION ALL
SELECT 5 lt_id, 'G' idx_2, 'Y' col_1 FROM dual)
SELECT 'new_way' qry,
t1.mt_id,
t1.val,
CASE WHEN t2.col_1 is null or t2.col_1 != 'Y' THEN 'SF01' END new_stop_val
FROM t1
LEFT OUTER JOIN t2 ON t1.mt_id = t2.lt_id AND idx_2 = 'G'
UNION ALL
SELECT 'old_way' qry,
t1.mt_id,
t1.val,
CASE WHEN NOT EXISTS (SELECT 1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G')
OR (SELECT t2.COL_1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G') IS NULL
OR (SELECT t2.COL_1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G') <> 'Y'
THEN 'SF01'
END new_stop_val
FROM t1
ORDER BY mt_ID, qry;
QRY MT_ID VAL NEW_STOP_VAL
------- ---------- ---------- ------------
new_way 1 10 SF01
old_way 1 10 SF01
new_way 2 20 SF01
old_way 2 20 SF01
new_way 3 30 SF01
old_way 3 30 SF01
new_way 4 40 SF01
old_way 4 40 SF01
new_way 5 50
old_way 5 50
您的条件可以有效地重新写入为检查lt.col_1字段的值是否不等于“Y”(即
lt.col_1为null或lt.col_1!=“Y”
)。我已经构建了一个快速测试用例,使用您的旧检查方法和新的:
WITH t1 AS (SELECT 1 mt_id, 10 val FROM dual UNION ALL
SELECT 2 mt_id, 20 val FROM dual UNION ALL
SELECT 3 mt_id, 30 val FROM dual UNION ALL
SELECT 4 mt_id, 40 val FROM dual UNION ALL
SELECT 5 mt_id, 50 val FROM dual),
t2 AS (SELECT 2 lt_id, 'F' idx_2, NULL col_1 FROM dual UNION ALL
SELECT 3 lt_id, 'G' idx_2, NULL col_1 FROM dual UNION ALL
SELECT 4 lt_id, 'G' idx_2, 'N' col_1 FROM dual UNION ALL
SELECT 5 lt_id, 'G' idx_2, 'Y' col_1 FROM dual)
SELECT 'new_way' qry,
t1.mt_id,
t1.val,
CASE WHEN t2.col_1 is null or t2.col_1 != 'Y' THEN 'SF01' END new_stop_val
FROM t1
LEFT OUTER JOIN t2 ON t1.mt_id = t2.lt_id AND idx_2 = 'G'
UNION ALL
SELECT 'old_way' qry,
t1.mt_id,
t1.val,
CASE WHEN NOT EXISTS (SELECT 1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G')
OR (SELECT t2.COL_1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G') IS NULL
OR (SELECT t2.COL_1 FROM t2 WHERE t2.LT_ID = t1.MT_ID AND t2.IDX_2 = 'G') <> 'Y'
THEN 'SF01'
END new_stop_val
FROM t1
ORDER BY mt_ID, qry;
QRY MT_ID VAL NEW_STOP_VAL
------- ---------- ---------- ------------
new_way 1 10 SF01
old_way 1 10 SF01
new_way 2 20 SF01
old_way 2 20 SF01
new_way 3 30 SF01
old_way 3 30 SF01
new_way 4 40 SF01
old_way 4 40 SF01
new_way 5 50
old_way 5 50
请通读链接并尝试创建要更新的过程。如果您遇到任何困难,请联系我们。你的
案例
表达式看起来很奇怪。你选择同一个表9次,你怎么能期望良好的性能?尝试只选择一次表大。\u TBL。请通读链接并尝试创建要更新的过程。如果您遇到任何困难,请联系我们。你的案例
表达式看起来很奇怪。你选择同一个表9次,你怎么能期望良好的性能?请尝试只选择一次表大。\u TBL。您能告诉我这条ON
子句将要完成什么吗:(tgt.rowid=src.r\u id)
?我们是否应该将SELECT
子句改为USING(选择mt.rowid、mt.mt\u id、mt.idx\u 2
和ON
子句改为(tgt.mt\u id=src.mt\u id和tgt.idx\u 2='G')
?我使用rowid作为联接条件,因为我不知道表的主键。如果愿意,您可以切换到使用主键,只要您不尝试更新任何主键列(此时您必须在rowid上联接)。您能告诉我这条关于的子句将要完成什么吗:(tgt.rowid=src.r\u id)
?我们是否应该使用(选择mt.rowid、mt.mt\u id、mt.idx\u 2
和关于
子句的(tgt.mt\u id=src.mt\u id和tgt.idx\u 2='G')将子句更改为
?我使用rowid作为联接条件,因为我不知道表的主键。如果愿意,您可以切换到使用主键,只要您不尝试更新任何主键列(此时您必须在rowid上联接)。
MERGE INTO main_table tgt
USING (SELECT mt.rowid, r_id,
CASE WHEN lt.col_1 is null or lt.col_1 != 'Y' THEN 'SF01'
WHEN lt.col_2 is null or lt.col_2 != 'Y' THEN 'SF02'
ELSE mt.stop_flag -- null
END new_stop_flag,
CASE WHEN NVL(lt.col1, 'N') != 'Y' THEN 'E'
WHEN NVL(lt.col2, 'N') != 'Y' THEN 'E'
ELSE mt.es -- null
END new_es,
CASE WHEN NVL(lt.col_1, 'N') != 'Y' THEN 'W'
WHEN NVL(lt.col_2, 'N') != 'Y' THEN 'W'
ELSE mt.pw
END new_pw
FROM main_table mt
LEFT JOIN large_table lt ON (mt.mt_id = lt.lt_id AND lt.idx_2 = 'G')
WHERE mt.stop_flag IS NULL
AND mt.idx_2 = 'G'
AND mt.es IS NULL
AND mt.ss = 'C'
AND mt.pw = 'A') src
ON (tgt.rowid = src.r_id)
WHEN MATCHED THEN
UPDATE tgt.stop_flag = src.new_stop_flag,
tgt.es = src.es,
tgt.pw = src.pw;