1

我有一个Students表,其中包含 7 个地址字段。

我需要为地址字段有回车 的学生每人显示 1 行,如果有的话。

这之后就很迷茫了。

9 列第 1 列-学生 ID2-8 列- 7 个地址字段)必须包含具有回车符的列名列表(例如 addr_1, addr_3, 1 用于每个学生 ID,以逗号分隔)

10 列必须包含非法字符(在本例中为回车)。

该代码必须进一步扩展到不时识别的其他非法字符,并且必须生成报告。

我无法在第 9 列和第 10 列工作。任何人都可以帮忙吗?

SELECT pty.id,
a.addr_1,
a.addr_2,
a.addr_3,
a.addr_4,
a.addr_5,
a.addr_6,
a.addr_7
FROM addr a 
inner join contact cON a.idf = c.add_idf
inner join pty ON c.pty_id = pty.id
WHERE 
INSTR(a.addr_1,CHR(13)) > 0 OR
INSTR(a.addr_2,CHR(13)) > 0 OR
INSTR(a.addr_3,CHR(13)) > 0 OR
INSTR(a.addr_4,CHR(13)) > 0 OR
INSTR(a.addr_5,CHR(13)) > 0 OR
INSTR(a.addr_6,CHR(13)) > 0 OR
INSTR(a.addr_7,CHR(13)) > 0;
4

3 回答 3

1

第 9 列将带有case when instr(...) then 1 else 0 end || case when instr(...) then

create table tmp (vc varchar2(20),  vc2 varchar2(20));
insert into tmp values ('abcd','bcda');
insert into tmp values ('bcd','bcda');

select 
  case when instr(vc,'a')>0 then 'col1' else null end ||
  case when instr(vc2,'a')>0 then 'col2' else null end 
from tmp;

至于第二个问题,你可以放在'RETURN'第 10 列。由于您只寻找一个禁止字符并且只获得包含它的行。当你想出一个处理几个禁止字符的解决方案时,我会更新。

于 2013-01-18T13:56:58.960 回答
1

这听起来像是一个家庭作业问题。所以,让我给你一些提示:

(1) 可以使用语法生成表,如:

select chr(13) as badchar from dual union all
select '!' . . .

(2) 你可以cross join把这个放入表中并使用一个非常相似的where子句。

(3) 然后您可以从表中选择坏字符。

(4) 你需要一个聚合。

实际上,我倾向于放弃每个学生一排的要求,而是每个学生/坏角色一排。这是一种方法:

select a.id,
       a.addr_1, a.addr_2, a.addr_3, a.addr_4, a.addr_5, a.addr_6, a.addr_7,
       ((case when INSTR(a.addr_1, b.badChar) > 0 then 'addr_1,' else '' end) ||
        (case when INSTR(a.addr_2, b.badChar) > 0 then 'addr_2,' else '' end) ||
        (case when INSTR(a.addr_3, b.badChar) > 0 then 'addr_3,' else '' end) ||
        (case when INSTR(a.addr_4, b.badChar) > 0 then 'addr_4,' else '' end) ||
        (case when INSTR(a.addr_5, b.badChar) > 0 then 'addr_5,' else '' end) ||
        (case when INSTR(a.addr_6, b.badChar) > 0 then 'addr_6,' else '' end) ||
        (case when INSTR(a.addr_7, b.badChar) > 0 then 'addr_7,' else '' end)
       ) as addrs,
       b.badChar
from a cross join
     (select chr(13) as badChar from dual) as b
WHERE INSTR(a.addr_1, b.badChar) > 0 OR
      INSTR(a.addr_2, b.badChar) > 0 OR
      INSTR(a.addr_3, b.badChar) > 0 OR
      INSTR(a.addr_4, b.badChar) > 0 OR
      INSTR(a.addr_5, b.badChar) > 0 OR
      INSTR(a.addr_6, b.badChar) > 0 OR
      INSTR(a.addr_7, b.badChar) > 0;

它在列名的末尾留下一个额外的逗号。这可以通过将其设为子查询并在下一级进行字符串操作来删除。

将所有 badchars 放在一行上需要聚合。但是,我不清楚在这种情况下第 9 列和第 10 列将包含什么。

于 2013-01-18T13:57:57.160 回答
0

在类似的情况下,我选择了一个大锤子,只是检测到带有 REGEXP_LIKE(col1,'[:cntrl:]') 的非打印控制代码,因为接下来有人会添加一个标签或其他破坏数据的东西。

要求在列上放置检查约束以防止这种情况发生是不是太过分了?

于 2013-01-18T21:05:44.830 回答