2013-01-18 24 views
1

我有一個Students表,其中包含7個地址字段。顯示包含回車符的列

我需要爲學生每行顯示,其中地址字段有回車符,如果有的話。

在此之後它感到困惑。

第九列第一列 - 學生ID2-8列 - 7地址字段)必須包含其中有一個回車符(如ADDR_1列名的列表,addr_3 ,1爲用逗號分隔每個學生ID)

第十列必須包含非法字符(在這種情況下,回車)。

此代碼必須進一步擴展到其他現在確定的非法字符,並且必須生成報告。

我無法在第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; 
+0

這功課嗎? –

+0

讓我猜猜,一個前端應用程序扼殺非打印字符,所以答案是「修復數據」。您將不斷重新將這些字符引入數據,修復應用層 – tbone

+0

您可以使用REPLACE f-n將CHR(13)替換爲查詢中的任何其他字符。雖然它應該像下面這樣工作:SELECT INSTR('1'|| chr(13)||'2',chr(13))str FROM dual – Art

回答

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列在這種情況下會包含什麼。

+0

這不是一個家庭作業,而是一個需要的東西,我們工作的客戶.. 我將如何獲得列名稱的列表。必須是一個獨立的軟件包,它需要從all_tab_columns和東西查詢。我完全困惑。你能否詳細說明請... – Avinash

+0

好的戈登..解決方案似乎很簡單。作爲一個週末,我只能在星期一進行測試..如果有任何問題,請告訴你。 最後,是的你是正確的..每行ID /字符1行... :) :) – Avinash

+0

可能喜歡「where instr(a.addr_1 || a.addr_2 || a.addr_3 ...,b.badChar )> 0「,並將最有可能包含壞字符的列放在列表中 –

1

第九欄是用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列。既然你只是在尋找一個被禁止的角色,並且只能得到擁有它的行。 當你想出一個處理幾個被禁止的字符的解決方案時,我會更新。

0

在類似的情況下,我去了一個Big Hammer,剛剛用REGEXP_LIKE(col1,'[:cntrl:]')檢測到非打印控制代碼,因爲接下來有人會添加一個選項卡或其他破解的內容數據。

爲了防止這種情況發生,請求檢查限制放在列上是否太多了?

相關問題