SQL - 从一个表插入另一个表但操作数据

时间:2018-06-13 14:19:04

标签: sql database oracle

我正在尝试使用以下脚本将数据从一个表复制到另一个表:

insert into test_report
( company_id
, report_id
, brch_code
, definition
, description
, editable_flag
, executable_flag
, name
, report_type ) 
values
( 2420
, 'RP00002004'
, '0001'
, (select definition from test_template_report where template_id='RP00001242')
, (select description from test_template_report where template_id='RP00001242')
, (select editable_flag from test_template_report where template_id='RP00001242')
, (select executable_flag from test_template_report where template_id='RP00001242')
, (select name from test_template_report where template_id='RP00001242')
, '01' );

这很好用,但是定义字段包含需要稍微修改的XML。

以下是定义数据的一部分:

<listdef page='25'><reportId>RP00000390</reportId><name>Fund Transfer</name><description>Fund Transfer</description>

根据插入脚本,<reportId>RP00000390</reportId>部分需要更改为 RP00002004

如下所示:

<listdef page='25'><reportId>RP00002004</reportId><name>Fund Transfer</name><description>Fund Transfer</description>

这可能吗?

2 个答案:

答案 0 :(得分:2)

您可以将XMLQuery与modify ... replace value of node

一起使用
insert into test_report (company_id,report_id,brch_code,definition,description,
  editable_flag,executable_flag,name,report_type)
select 2420, 'RP00002004', '0001',
  XMLQuery('copy $i := $d modify
      (for $j in $i//reportId return replace value of node $j with $r)
      return $i'
    passing definition as "d", 'RP00002004' as "r"
    returning content),
  description, editable_flag, executable_flag, name, '01'
from test_template_report where template_id='RP00001242';

您不需要模板表中的所有单独选择,单个插入选择就可以。

XML操作假定definition是XMLType;如果不是,您可以将其转换为passing子句中的一个,即passing XMLType(definition) as "d"reportId节点(或节点)的值将替换为作为"r"传递的字符串。

作为替换发生的快速静态演示,使用内联提供的XML作为字符串文字:

select
  XMLQuery('copy $i := $d modify
      (for $j in $i//reportId return replace value of node $j with $r)
      return $i'
    passing XMLType(q'[<listdef page='25'><reportId>RP00000390</reportId><name>Fund Transfer</name><description>Fund Transfer</description></listdef>]') as "d",
      'RP00002004' as "r"
    returning content)
  as modified_definition
from dual;

MODIFIED_DEFINITION                                                                                                           
------------------------------------------------------------------------------------------------------------------------------
<listdef page="25"><reportId>RP00002004</reportId><name>Fund Transfer</name><description>Fund Transfer</description></listdef>

Read more

答案 1 :(得分:0)

replace函数将一个文本字符串替换为另一个文本字符串,因此您可以更改

definition

replace(definition, '<reportId>RP00000390</reportId>', '<reportId>RP00002004</reportId>')

您还可以一次性从test_template_report获取所需的所有列:

insert into test_report
     ( company_id
     , report_id
     , brch_code
     , definition
     , description
     , editable_flag
     , executable_flag
     , name
     , report_type )
select 2420
     , 'RP00002004'
     , '0001'
     , replace(tr.definition, '<reportId>RP00000390</reportId>', '<reportId>RP00002004</reportId>')
     , tr.description
     , tr.editable_flag
     , tr.executable_flag
     , tr.name
     , '01'
from   test_template_report tr
where  tr.template_id = 'RP00001242';

如果您想要替换reportIf而不只是'RP00000390'的任何值,您可以使用regexp_replace

insert into test_report
     ( company_id
     , report_id
     , brch_code
     , definition
     , description
     , editable_flag
     , executable_flag
     , name
     , report_type )
select 2420
     , 'RP00002004'
     , '0001'
     , regexp_replace(definition,'<reportId>[^<]+</reportId>','<reportId>RP00002004</reportId>')
     , tr.description
     , tr.editable_flag
     , tr.executable_flag
     , tr.name
     , '01'
from   test_template_report tr
where  tr.template_id = 'RP00001242';