Oracle 中的动态更新查询
Posted
技术标签:
【中文标题】Oracle 中的动态更新查询【英文标题】:Dynamic Update Query in Oracle 【发布时间】:2010-02-23 17:33:08 【问题描述】:我正在尝试为表创建标准 UPDATE 查询。但是,如果满足某些条件,则应在 UPDATE 语句中包含/排除某些列。
例如:
UPDATE TBL_PROJECT SET
REVISION_COUNT = V_REVISION_COUNT
,PRIMARY_BRANCH = IN_PRIMARY_BRANCH
,PROJECT_STATUS = IN_PROJECT_STATUS
...
WHERE PROJECT_ID = IO_PROJECT_ID
AND REVISION_COUNT = IO_REVISION_COUNT
RETURNING REVISION_COUNT INTO IO_REVISION_COUNT';
但是,该表有两列供提交者和批准者使用。因此,如果状态设置为已提交或已批准,我希望更新这些列。例如。
IF IN_PROJECT_STATUS = 'SUB'
UPDATE TBL_PROJECT SET
SUBMITTED_DATE = SYSDATE
ELSIF IN_PROJECT_STATUS = 'APP'
UPDATE TBL_PROJECT SET
APPROVED_DATE = SYSDATE
END;
我还需要返回 REVISION_COUNT 和受影响的行数(rowcount)来检查更新是否成功。
编写此查询的最佳方式是什么?我假设动态查询比使用 if-elsif-else 语句更好,因为整个查询在每个块中几乎重复。
【问题讨论】:
【参考方案1】:您可以编写一个UPDATE
,并使用DECODE
(或CASE
)仅在in_project_status
匹配时更新日期:
...
, submitted_date = DECODE( in_project_status, 'SUB', SYSDATE, submitted_date )
, approved_date = DECODE( in_project_status, 'APP', SYSDATE, approved_date )
...
这样可以避免重复的UPDATE
。
【讨论】:
@Matt McCormick:在 10g 上,使用CASE
而不是 DECODE
【参考方案2】:
案例示例:
UPDATE TBL_PROJECT
SET REVISION_COUNT = v_revision_count,
PRIMARY_BRANCH = IN_PRIMARY_BRANCH,
PROJECT_STATUS = IN_PROJECT_STATUS
...
SUBMITTED_DATE = CASE WHEN IN_PROJECT_STATUS = 'APP' THEN SYSDATE ELSE SUBMITTED_DATE END,
APPROVED_DATE = CASE WHEN IN_PROJECT_STATUS = 'SUB' THEN SYSDATE ELSE APPROVED_DATE END,
WHERE PROJECT_ID = IO_PROJECT_ID
AND REVISION_COUNT = IO_REVISION_COUNT
RETURNING REVISION_COUNT INTO IO_REVISION_COUNT
【讨论】:
以上是关于Oracle 中的动态更新查询的主要内容,如果未能解决你的问题,请参考以下文章