【问题标题】:Oracle Replace functionOracle 替换功能
【发布时间】:2013-05-18 15:20:57
【问题描述】:

选择查询时,我需要用 Table2 的值替换 Table1 的字段值。

例如:

表1:

Org                  Permission
--------------------------------------
Company1             1,3,7
Company2             1,3,8

表2:

Permission          Permission
--------------------------------------
1                   Read
3                   Write
7                   Execute
8                   Delete

我需要这样的:

Org                  Permission
--------------------------------------
Company1             Read,Write,Execute
Company2             Read,Write,Delete

【问题讨论】:

  • 您能否编辑问题以显示您迄今为止所做的尝试?另外,您是否意识到当前的数据结构违反了第一范式?

标签: mysql sql oracle replace compare


【解决方案1】:

在 Oracle 中,您可以运行这个 PL/SQL 块,它会完成所有工作:

begin
  for x in (
    select permission, descr from table2
  ) loop
    update table1 set permission = replace(permission, x.permission, x.descr);
  end loop;
  commit;
end
/

我使用这个脚本创建了一个模式:

create table table1(
  org varchar2(100),
  permission varchar2(1000)
);

create table table2(
  permission varchar2(100),
  descr varchar2(1000)
);

insert into table1(org, permission) values ('Company1', '1,3,7');
insert into table1(org, permission) values ('Company2', '1,3,8');
insert into table2(permission, descr) values ('1', 'Read');
insert into table2(permission, descr) values ('7', 'Execute');
insert into table2(permission, descr) values ('8', 'Delete');

【讨论】:

    【解决方案2】:

    其中一个很棒的解决方案为这种替换提供了here

    它只是创建了一个multiple_replace函数:

    CREATE TYPE t_text IS TABLE OF VARCHAR2(256);
    
    CREATE FUNCTION multiple_replace(
      in_text IN VARCHAR2, in_old IN t_text, in_new IN t_text
    )
      RETURN VARCHAR2
    AS
      v_result VARCHAR2(32767);
    BEGIN
      IF( in_old.COUNT <> in_new.COUNT ) THEN
        RETURN in_text;
      END IF;
      v_result := in_text;
      FOR i IN 1 .. in_old.COUNT LOOP
        v_result := REPLACE( v_result, in_old(i), in_new(i) );
      END LOOP;
      RETURN v_result;
    END;
    

    然后你可以使用这个查询来替换:

    UPDATE Table1
    SET permission_id = multiple_replace(Permission, (select distinct Permission from table2), 
            (select distinct Permission_name from table2));
    

    【讨论】:

      【解决方案3】:

      如果您不想更新现有表而只想选择数据,那么您可以使用这个有点费力的查询。

      http://sqlfiddle.com/#!4/22909/4

      WITH changed_table AS
           (SELECT val1, EXTRACTVALUE (x.COLUMN_VALUE, 'e') val2new
              FROM (SELECT val1, val2 xml_str
                      FROM table1),
                   TABLE (XMLSEQUENCE (XMLTYPE (   '<e><e>'
                                                || REPLACE (xml_str, ',', '</e><e>')
                                                || '</e></e>'
                                               ).EXTRACT ('e/e')
                                      )
                         ) x)
      SELECT ct.val1, listagg(table2.val2,',') within group (order by table2.val2) val2
        FROM changed_table ct, table2 table2
       WHERE ct.val2new = table2.val1
      group by ct.val1;
      

      我已使用 XMLTYPE 将逗号分隔的数字分隔为行。然后将行与第二个表连接以获得描述,最后使用 LISTAGG 函数形成逗号分隔的字符串。不知道这个查询效率如何。我同意马克班尼斯特的评论。

      【讨论】:

        猜你喜欢
        • 2021-10-05
        • 2019-08-17
        • 2015-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-23
        相关资源
        最近更新 更多