如何在Oracle的同一列值内的不同模式上使用REPLACE进行更新?

时间:2018-12-14 21:32:17

标签: sql oracle replace sql-update oracle12c

以下是我在table FOO中拥有的示例数据-

        CREATE TABLE FOO 
           ( 
            NUMBERS VARCHAR2(4000 CHAR)
           );

           INSERT INTO FOO VALUES ('One,Five,Seven');
           INSERT INTO FOO VALUES ('One,Two,Three');
           INSERT INTO FOO VALUES ('Five,Five,Seven');
           INSERT INTO FOO VALUES ('Zero,Five,Seven');
       /*  .
           .
           .
          and so on.. */

SELECT * FROM FOO;

the sample data

我想写一条更新语句,用相应的数字替换文本。所以输出应该像-

Output

2 个答案:

答案 0 :(得分:1)

这是一种方法。这很愚蠢,但是问题也就这样了,所以我并不觉得很糟糕。确实可以。

update foo
set numbers = (select listagg(decode(token,'Zero',0,'One',1,'Two',2,'Three',3,
                       'Four',4,'Five',5,'Six',6,'Seven',7,'Eight',8,'Nine',9)
                             , ',') within group (order by ord)
               from   json_table('["' || replace(numbers, ',', '","') || '"]',
                                 '$[*]'
                                 columns token varchar2 path '$', 
                                         ord for ordinality)
              )
;

select * from foo;

NUMBERS             
--------------------
1,5,7
1,2,3
5,5,7
0,5,7

答案 1 :(得分:1)

这是一个更加愚蠢的技巧(仍然正确-应该在Oracle 12.1和更高版本中工作)。作为可能的例子,它更有趣。

update /*+ with_plsql */ foo
  set numbers = (
    with
      function list_replace(str varchar2) return varchar2 as
        p integer := instr(str,',');
        function single_replace(token varchar2) return varchar2 as
        begin
          return case token when 'Zero'  then '0' when 'One'   then '1'
                            when 'Two'   then '2' when 'Three' then '3'
                            when 'Four'  then '4' when 'Five'  then '5'
                            when 'Six'   then '6' when 'Seven' then '7'
                            when 'Eight' then '8' when 'Nine'  then '9' end;
        end single_replace;
      begin
        return case p when 0 then single_replace(str)
                      else single_replace(substr(str,1,p-1)) || ',' ||
                           list_replace(substr(str,p+1)) end;
      end list_replace;
    select list_replace(numbers) from dual
  )
/