更新嵌套案例

时间:2016-05-10 22:08:56

标签: oracle nested sql-update case

我正在使用连接到Oracle 11g的TOAD。

我正在解析一个地址字段,其中包含楼宇编号,街道名称,街道类型,方向,子单元和思域编号后缀类型。

由于允许输入地址的复杂性仍然有效(或者只是我现在忽略了不正确的信息),我不得不做一些非常具体的正则表达式来拆分建筑物编号,单位和思域号后缀类型。

我在更新单个字段之前使用了case语句

UPDATE TEMP_PARSE_EXIST
SET ADT_ACT =
CASE
    WHEN REGEXP_LIKE(ADRS, 'P\.?\s?O\.?\s+BOX', 'i') THEN 'PO BOX'
    WHEN REGEXP_LIKE(ADRS,'(\s|^)(RR|GD)(\s|$)', 'i') THEN 'QUERY ERROR: RR OR GD'
    ELSE NULL
END
WHERE ADT_ACT IS NULL;

但我现在需要的是不同的,因为我将更新的字段将取决于案例并且它一直给我一个缺少的set关键字错误。

UPDATE TEMP_PARSE_EXIST
CASE
    WHEN REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+\s\w+', 'i'), '(ABBEY|ACRES|ALLÉE|ALLEY|AUT|AUTOROUTE|AV|AVE|AVENUE|BAY|BEACH|BEND|BLVD|BOUL|BOULEVARD|BYPASS|WYND)$', 'i') THEN 
        CASE
            WHEN REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '^\w+(\s?-\s?)\d+$') THEN SET ADT_ACT = 'CASE 1', V_NUM = REGEXP_SUBSTR(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '\d+$')
            WHEN REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '^\w+(\s?-\s?)\d+(ST|ND|RD|TH)$') THEN SET ADT_ACT = 'CASE 2', V_STREET_NAME = REGEXP_SUBSTR(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '\d+(ST|ND|RD|TH)$')
            ELSE SET ADT_ACT = 'FIRST ERROR SPOT'
        END
END
WHERE ADT_ACT IS NULL;

这只是解决这些信息的许多案例的开始。因此将会有更多它们遵循,嵌套的case语句很有用。是的,这可以通过常规案例陈述来完成,但行数会更长,并且会重复工作。

我在嵌套case语句中找到的源总是用于select语句或plsql,我需要它用于UPDATE。 https://community.oracle.com/thread/1094856?start=0&tstart=0

2 个答案:

答案 0 :(得分:1)

UPDATE statement的语法是:

UPDATE statement syntax

Update_set_clause :: =

UPDATE set clause

你做不到:

UPDATE table_name
CASE WHEN ... THEN SET ...
     WHEN ... THEN SET ...

将它分成多个语句可能更容易:

UPDATE TEMP_PARSE_EXIST
SET ADT_ACT = 'CASE 1',
    V_NUM   = REGEXP_SUBSTR(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '\d+$')
WHERE ADT_ACT IS NULL
AND   REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+\s\w+', 'i'), '(ABBEY|ACRES|ALLÉE|ALLEY|AUT|AUTOROUTE|AV|AVE|AVENUE|BAY|BEACH|BEND|BLVD|BOUL|BOULEVARD|BYPASS|WYND)$', 'i')
AND   REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '^\w+(\s?-\s?)\d+$');

UPDATE TEMP_PARSE_EXIST
SET ADT_ACT = 'CASE 2',
    V_STREET_NAME = REGEXP_SUBSTR(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '\d+(ST|ND|RD|TH)$')
WHERE ADT_ACT IS NULL
AND   REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+\s\w+', 'i'), '(ABBEY|ACRES|ALLÉE|ALLEY|AUT|AUTOROUTE|AV|AVE|AVENUE|BAY|BEACH|BEND|BLVD|BOUL|BOULEVARD|BYPASS|WYND)$', 'i')
AND   REGEXP_LIKE(REGEXP_SUBSTR(ADRS, '^\w+(\s?-\s?)\w+'), '^\w+(\s?-\s?)\d+(ST|ND|RD|TH)$');

...

<强>更新

可以使正则表达式更简单(或者至少减少表达式的重复和嵌套):

UPDATE TEMP_PARSE_EXIST
SET ADT_ACT = 'CASE 2',
    V_STREET_NAME = REGEXP_SUBSTR( ADRS, '^\w+(\s?-\s?)(\d+(ST|ND|RD|TH))', 1, 1, 'i', 2 )
WHERE ADT_ACT IS NULL
AND   REGEXP_LIKE( '^\w+(\s?-\s?)\d+(ST|ND|RD|TH)\s\w*(ABBEY|ACRES|ALLÉE|ALLEY|AUT|AUTOROUTE|AV|AVE|AVENUE|BAY|BEACH|BEND|BLVD|BOUL|BOULEVARD|BYPASS|WYND)', 'i' );

答案 1 :(得分:0)

CASE表达式中的SET关键字和赋值无效。

遵循THEN和ELSE关键字必须是一个计算结果为值的表达式。返回的表达式可以是另一个CASE表达式,可以嵌套CASE表达式。

在CASE表达式中不能包含UPDATE的SET关键字。

如果要更新列,第一个表单是正确的......

 UPDATE mytable
    SET col = expr
  WHERE ...

表达式可以是&#34;嵌套的CASE&#34;。如果您不想更新列的条件,则返回列的当前值

 UPDATE mytable
    SET mycol = CASE
                  WHEN foo = bar 
                    THEN CASE
                           WHEN fee > 0
                             THEN ...
                           WHEN fi = 'abc'
                             THEN ...
                           ELSE mycol
                         END
                  ELSE mycol
                END
  WHERE ...