选择无效字符的 Oracle SQL 问题

Posted

技术标签:

【中文标题】选择无效字符的 Oracle SQL 问题【英文标题】:Oracle SQL issue with selecting invalid chars 【发布时间】:2013-04-12 15:07:55 【问题描述】:

我遇到了在 Oracle 10g 中将两个单元格合并为一个单元格时创建的无效字符的问题。

然后将字符串插入到 xml 文件中,如果插入无效字符,则会破坏 xml 文件。 (XML 最大可达 8gb,修复起来很麻烦,所以我需要在每天创建 xml 之前自动运行它。

我一直在做的是找到一个版本,如下所示。

select * from (select ar_journal.jnlinpnum,debtor_ref,dump(narration) as dn,narration from ENERGYDB.ar_journal) where dn like '%31%' and dn not like '%=31:%';

但是,这只会带回一个字符,并且会出现很多字符,需要删除字符 0 - 31 和 226 - 256。

所以我尝试了这个,

create table tmp_charprefix(
charf1 Varchar2 (10), charf2 varchar2 (10)) ;


INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%27%', '%=27%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%28%', '%=28%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%29%', '%=29%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%30%', '%=30%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%31%', '%=31%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%60%', '%=60%');
INSERT INTO tmp_charprefix (charf1, charf2) VALUES ('%62%', '%=62%');

以上是我要寻找的价值观。

create table tmp_charfix as
select aj.jnlinpnum, aj.type_jnl, ajt.jnl_descr, ajei.reason_no, ar.reason_descr, aj.narration
from ar_journal aj, ar_jnl_type ajt, ar_jnl_extra_info ajei, ar_reason ar
where ajt.type_jnl = aj.type_jnl
and ajei.jnlinpnum = aj.jnlinpnum
and ajei.reason_no = ar.reason_no
and aj.jnlinpnum in ( select jnlinpnum from (
select ar_journal.jnlinpnum, debtor_ref, dump(narration) as dn, narration from energydb.ar_journal)
where dn like (select charf1 from tmp_charprefix tmo)
and dn not like (select charf2 from tmp_charprefix tmt)
and substr(tmo.charf1,2,8) = substr(tmt.charf2,3,8) ;

-- 尝试调用 charf1 的子字符串并将其与 charf2 的子字符串匹配

我收到以下错误,但我不确定我是否在最后一行做一些可能的事情

SQL Error: ORA-00907: missing right parenthesis
00907. 00000 -  "missing right parenthesis"
*Cause:    
*Action:

任何帮助将不胜感激,在过去的几个小时里,我一直坚持这一点。

谢谢,

【问题讨论】:

您可能需要考虑使用 strem 编辑器来自动对生成的 xml 进行后处理,例如。 sed。对于基于正则表达式的简单替换,此解决方案可能会在性能方面为您提供优势。 【参考方案1】:

这是一个建议而不是一个答案,但它太长了,不适合 cmets,所以我必须将它作为答案呈现。

建议:缩进你的代码。这样会更容易发现问题。

create table tmp_charfix as
  select
    aj.jnlinpnum,
    aj.type_jnl,
    ajt.jnl_descr,
    ajei.reason_no,
    ar.reason_descr,
    aj.narration
  from
    ar_journal aj,
    ar_jnl_type ajt,
    ar_jnl_extra_info ajei,
    ar_reason ar
  where ajt.type_jnl = aj.type_jnl
    and ajei.jnlinpnum = aj.jnlinpnum
    and ajei.reason_no = ar.reason_no
    and aj.jnlinpnum in ( -- OPEN PAREN HERE WITH NO CLOSING PAREN
      select jnlinpnum from (
        select ar_journal.jnlinpnum, debtor_ref, dump(narration) as dn, narration
        from energydb.ar_journal
      ) -- this parenthesis is also trouble, coming between FROM and WHERE
      where dn like (select charf1 from tmp_charprefix tmo)
        and dn not like (select charf2 from tmp_charprefix tmt)
        and substr(tmo.charf1,2,8) = substr(tmt.charf2,3,8)
    -- Oracle is still waiting for a closing parenthesis here...

【讨论】:

【参考方案2】:

选择相关记录使用

    select jnlinpnum
         , debtor_ref
         , dn
         , narration
      from (
                select ar_journal.jnlinpnum
                     , debtor_ref
                     , dump(narration) as dn
                     , narration
                     , regexp_instr ( dn, '([^[:digit:]=]|^)(27|28|29|30|31|60|62)([^:[:digit:]]|$)' ) as dn_occurrence
                  from ENERGYDB.ar_journal
           )
     where dn_occurrence > 0
         ;

可以使用regexp_replace 函数执行实际替换。 检查性能,但是,使用 regexp_class 函数可能无法使用 8gb 输出。

【讨论】:

以上是关于选择无效字符的 Oracle SQL 问题的主要内容,如果未能解决你的问题,请参考以下文章

oracle 创建表提示字元无效,求高手指点迷精。

Mybatis 批量更新 ORA-00911: 无效字符的错误

Oracle SQL:插入失败 ORA-01722:无效数字,数据是数字而不是字符串,为啥会失败?

表更改后 Oracle SQL 过程变得无效

Oracle 动态SQL 注意细节 ORA-00911: 无效字符

plsql工具在oracle数据库中使用comment语句给表加备注的时候单条执行没问题,批量多条执行就报无效字符了