2013-04-03 60 views
5

我開始學習Oracle PL/SQL,並且下載了Oracle Database 10g Express,其中包含相同的示例和問題。Oracle PL/SQL字符串格式化

有一個我無法解決的問題。

的問題是:

寫一個SQL查詢來檢索的第一個名字,姓氏,並在員工的代碼被發現如下的每個員工的代碼 : 首先刪除所有出現字符「i」和「l」,然後, 連接名稱的前六個字母,破折號「 - 」和 姓氏的最後六個字符,其中只有代碼的第一個和最後一個 字符應該是大寫。如果名稱不包含6個字母,則將下劃線(「」)放在該部分的末尾;如果 姓氏不包含六個字母,則將下劃線(「」)改爲 作品的開頭。根據姓氏排列列表,然後根據姓名排列 。

輸出必須是這樣的

enter image description here

我寫的東西,但它是完全以錯誤的,不清晰。我應該修復哪些部分?


SELECT employees.first_name, employees.last_name, 
replace(replace(first_name,'l',''),'i'), 
initcap(substr(rpad(employees.first_name,6,'_'),1,6)) || '-' || 

case when length(employees.last_name)>4 
then lower(substr(employees.last_name,-5,4)) 
else lower(substr(lpad(employees.last_name,5,'_'),-5,4)) end || 
upper(substr(employees.last_name,-1,1)) code 

FROM employees 
ORDER BY last_name, first_name; 

這是我的輸出(錯誤的) enter image description here

+0

在替換(替換(first_name,'l',''),'我')'你是什麼**實際上**替換「我」? –

+0

實際上我想用null或「」代替它,但是如果我添加替換字符,它會給出錯誤「參數數量太多」 – hakiko

+0

那麼爲什麼你不?爲什麼你只用空字符串替換「'l'」,而不是「'i」「? –

回答

3

你可以寫這樣的:

select first_name, last_name, f 
     ||'-' 
     ||substr(l, 1, length(l) - 1) 
     ||upper(substr(l, -1)) code 
    from (select first_name, last_name, 
       initcap(rpad(substr(translate(first_name, 'xil', 'x'), 1, 6), 6, 
         '_')) f, 
       lpad(substr(translate(last_name, 'xil', 'x'), 
          greatest(-6, -length(translate(last_name, 'xil', 'x')))), 6, 
          '_') 
          l 
      from employees); 

我一直以爲你只是想更換il而不是也IL。在這種情況下,translate的行爲與replace(replace(str, 'l', ''), 'i', '')相同。

+0

但它沒有給出預期的輸出。例如,列名非常複雜。列名應該像上面的圖片:) – hakiko

+0

@hakiko該示例是代碼部分。看到這裏添加其他兩個原始列:http://sqlfiddle.com/#!4/1fba7/1 – DazzaL

+0

這是很好的解決方案,但我已經有數據,表,列。在你的鏈接中,你用最好的方式創建了它。 :)關於已有數據的問題。 Oracle Express提供了用於執行示例的準備好數據庫:) – hakiko

0

此代碼,有些跟隨你原來的邏輯:

SELECT e."First_Name", e."Last_Name", 
     initcap(rpad(replace(replace(e."First_Name", 'l'), 'i'),6,'_')) 
     || '-' || 
     reverse(initcap(reverse(lpad(replace(replace(e."Last_Name", 'l'), 'i'),6,'_')))) "Code" 
FROM Employees e 
ORDER BY e."Last_Name", e."First_Name"; 

我使用REVERSE兩次,這樣我就可以使用INITCAP爲姓也。我也省略了REPLACE的第三個參數,因爲該函數默認使用空字符串。

這是我從你的數據部分構建的SQL Fiddle DEMO。隨意添加更多數據。

1

此代碼完全遵循您的要求: 替換列名和表名與所需的值

SELECT ENAME, JOB, INITCAP(RPAD(REPLACE(REPLACE(ENAME, 'I'), 'i'),6,'')) ' - ' || LPAD( 反向( INITCAP( SUBSTR(反向((REPLACE(REPLACE(JOB, 'I'), 'I'))), 1, 6))), 6, '') 代碼 FROM emp order by JOB,Ename