Oracle中的动态更新查询

时间:2010-02-23 17:33:08

标签: sql oracle plsql sql-update

我正在尝试为表创建标准的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语句更好,整个查询几乎在每个块中重复。

2 个答案:

答案 0 :(得分:5)

您可以撰写一个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

答案 1 :(得分: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