2017-08-29 103 views
0

我是SQL格式化函數的新手。我正在面對SQL格式化的一個問題。 這個SQL字符串需要的方式進行修改,以便它會給輸出這樣Sql格式化問題字符串

select 'TIME=~XX2015010106000001~XX2015010111000006TCODE=MEAL~XX2015010111450006TCODE=MEAL~XX2015010113000002~' as sub 
from dual); 

輸出

start=6am meal start=11am Meal end=11.45am end=1pm. 

與此字符串的問題是,它可以改變像TIME=~XX2017080213300001DST=T~XX2017080221300002~

起始標識符爲XX2017080213300001,以01結尾

結束標識符爲XX2017080221300002,結尾爲02

標識符的餐點XX2015010111000006與06

回答

0

結束對於它的樂趣,我用一對夫婦的CTE的分解步驟做這一切在SQL。如果你願意,你可以將這些步驟中的一部分移到PL/SQL中,以便於處理。第一個CTE創建一個名爲tbl的表,它是原始字符串。第二個創建一個名爲elements的表。 regexp_substr調用將出現波浪號分隔的元素,然後regexp_replace調用將您需要的小時/分鐘拉出。

然後,主要查詢從元素表中選擇,根據需要在格式化小時和am/pm時構建字符串。請注意正則表達式的處理您提到的替代格式。

一個告誡是這個代碼期望所有元素都存在,並且不允許午夜點心。

with tbl(str) as (
    select 'TIME=~XX2015010106000001~XX2015010111000006TCODE=MEAL~XX2015010111450006TCODE=MEAL~XX2015010113000002~' from dual 
), 
elements(starttime, mealstart, mealend, endtime) as (
    select 
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 2, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}01.*', '\1.\2'), 
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 3, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}06.*', '\1.\2'), 
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 4, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}06.*', '\1.\2'), 
    regexp_replace(regexp_substr(str, '(.*?)(~|$)', 1, 5, NULL, 1), 'XX\d{8}(\d{2})(\d{2})\d{2}02.*', '\1.\2') 
    from tbl 
) 
--select * from elements; 
select 'start=' || 
    case 
    when substr(starttime, 1, 2) < 12 then 
     to_char(starttime, 'TM')||'am' 
    when substr(starttime, 1, 2) = 12 then 
     to_char(starttime, 'TM')||'pm' 
    else to_char((starttime - 12), 'TM')||'pm' 
    end || 
    ' meal start=' || 
    case 
    when substr(mealstart, 1, 2) < 12 then 
     to_char(mealstart, 'TM')||'am' 
    when substr(mealstart, 1, 2) = 12 then 
     to_char(mealstart, 'TM')||'pm'  
    else to_char((mealstart - 12), 'TM')||'pm' 
    end || 
    ' Meal end=' || 
    case 
    when substr(mealend, 1, 2) < 12 then 
     to_char(mealend, 'TM')||'am' 
    when substr(mealend, 1, 2) = 12 then 
     to_char(mealend, 'TM')||'pm'  
    else to_char((mealend - 12), 'TM')||'pm' 
    end || 
    ' end=' || 
    case 
    when substr(endtime, 1, 2) < 12 then 
     to_char(endtime, 'TM')||'am' 
    when substr(endtime, 1, 2) = 12 then 
     to_char(endtime, 'TM')||'pm'  
    else to_char((endtime - 12), 'TM')||'pm' 
    end || 
    '.' time_string 
from elements; 

輸出:

TIME_STRING 
------------------------------------------- 
start=6am meal start=11am Meal end=11.45am end=1pm. 
+0

這是偉大的,但它不處理TIME =〜XX2017080213300001DST = T〜XX2017080221300002〜 –

+0

只有2個元素?因此,警告。我認爲你的不同格式是在此之後的DST。你的代碼將需要檢查元素的數量,並採取相應的行動。試一試! –

+0

嘗試過,但無法拿出東西..如果你能想出什麼東西,它會變成垃圾 –