【问题标题】:UPDATE NESTED CASE更新嵌套案例
【发布时间】:2016-05-10 22:08:56
【问题描述】:

我正在使用连接到 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;

但我现在需要的是不同的,因为我将要更新的字段将取决于具体情况,并且它不断给我一个缺少设置关键字的错误。

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 语句来完成,但是行会更长,并且会重复工作。

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

【问题讨论】:

    标签: oracle nested sql-update case


    【解决方案1】:

    UPDATE statement 的语法是:

    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' );
    

    【讨论】:

    • 如果我不能使用这样的嵌套 case 语句,我真的不期待这部分。谢谢你的回答。
    • Follow-up question;我认为REGEXP_SUBSTR 调用不需要'i' 标志?如果他们这样做,他们也需要位置和发生。
    【解决方案2】:

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

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

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

    如果要更新一列,第一种形式是正确的……

     UPDATE mytable
        SET col = expr
      WHERE ...
    

    表达式可以是“嵌套 CASE”。如果存在不想更新列的情况,则返回列的当前值

     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 ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-24
      • 1970-01-01
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多