好久沒有靜下心來寫東西了, 1 是沒有遇到好的案例 2 是最近好像 有點忙, 但又有點不知道自己在忙啥的感覺一樣。 強制自己靜下心寫東西, 但這時候 又覺得 自己囉嗦,闡述
點東西說了 很多, 又不知道自己 在說什麼。 好了廢話 不說 上正題
開發需要支援乙個 sql, 現有邏輯是 更新 a表 name 字段, 需要通過id關聯b表。然後把b的name,賦值給a表的name 值。 本來這個pl/sql 有。 但是現在 邏輯 變了。
說是 根據現在這個邏輯基礎上, 如果 b表 中多個資料字段type 欄位的值 為1, 則彙總b表所有name 的值,最後賦值給 a表資料。
這個需求 看似不難, 但是我後來做的過程中發現不少坑, 1 b表多條資料 和a表 關聯上, 但是滿足條件的 b表的name 值 一樣, 最終導致 a表中 的name 更新後
如『張三,張三,張三,張三』。 經過確認後 只要 乙個張三 就可以。 這個又設計到 欄位中重複資料去重?? 咋辦??
另外如果 b表資料關聯 有 20 多個!導致 a表的name 值過長! 此時 又經過確認, 擷取 3個 不同值 就可以, 本來我打算 擷取3 個最新的值,我想到的是,正規表示式。 但是木有必要。 能簡單點就簡單點吧。
考慮再三, 同乙個字串去重, 過於複雜 需要用 樹形函式 分隔, 我想到 用 想到 相鄰 函式 判斷 相等,則為空, 然後在分組 資料中把 name 值提取出來。
還有就是效能問題, a表 2個g,b表 2g。 2 g關聯 2g, 關聯分組,去重, 擷取。 更新 沒有優化的話, 估計在半小時 開外。 那就優化。最終sql
declare
cursor datacur is
with taba as(
select /*+ materialize */ order_id, main_wo_flag, party_name, count(1) over(partition by order_id) cnt from
uos_work_order uwo where main_wo_flag = '1' and uwo.arch_flag = 0
),tabb as(
select /*+ materialize */ order_id, main_wo_flag, party_name,
case when lag(party_name ) over(partition by order_id order by party_name) = party_name then null else party_name end party_name2
from taba where cnt>1
), tabc as( select /*+ materialize */ order_id, to_char(wm_concat( party_name2)) party_name from tabb
group by order_id
), tabd as( select /*+ materialize */ rowid rid,uot.id from uos_order_track uot )
select rid, regexp_replace(party_name,'^([^,]+)(,)([^,]+)(,)([^,]+)(,)(.*)$','\1\2\3\4\5\6') from
tabc, tabd where tabc.order_id = tabd.id order by 1;
type rowid_table_type is table of rowid index by pls_integer;
type cur_org_name_type is table of varchar2(255);
v_rowid rowid_table_type;
v_cur_org_name cur_org_name_type;
begin
open datacur;
loop
fetch datacur bulk collect into v_rowid, v_cur_org_name limit 20000;
dbms_output.put_line( 'v_rowid.count:'||v_rowid.count );
forall i in v_rowid.first ..v_rowid.last
update uos_order_track set cur_org_name = v_cur_org_name(i) where rowid = v_rowid(i) ;
commit;
exit when datacur%notfound;
end loop;
close datacur;
end;
綜合性能 穩定 在2 分組之內, 這個可是 大表,大表關聯更新哦。。。。
with taba as 提取資料, 提高效能
select rid, regexp_replace(party_name,'^([^,]+)(,)([^,]+)(,)([^,]+)(,)(.*)$','\1\2\3\4\5\6') 表示式 擷取 第三個逗號前面的 字串。
case when lag(party_name ) over(partition by order_id order by party_name) = party_name then null else party_name end party_name2 上一條資料 如果一樣 則為null.
wm_concat( party_name2) 合併字串, 10g中, 11g不建議用。
order by 1 很重要, 提公升效能關鍵, 這個就不說了, 太多,避免囉嗦。
fetch datacur bulk collect into v_rowid, v_cur_org_name limit 20000; 批量游標, 減少 sql 引警 搜尋引擎 頻換 切換。 limit 20000 防止 回滾段 壓力過大,
練習,求組合公式值
求組合數公式為 編一程式,輸入m和n 的值,求組合數。要求分別定義求階乘和求組合的函式,求組合數的函式呼叫求階乘的函式來實現求解,在 main 函式中,負責輸入輸出及呼叫求組合數的函式。include using namespace std int fac int int main int m,n ...
列舉值的組合使用
有時候列舉只返回一項會顯得不夠用,比如新建乙個列舉型別week它總共有7項分別代表週日到周一,宣告乙個week型別的列舉值work用來表示乙個人的值日安排,這個人的值日安排可能不止一天,如果work的值只能為week7個列舉項中的乙個顯然是不夠用的。這時候就需要用到列舉的組合。想要使用列舉的組合就需...
組合數學隨筆(更新中)
mathrm c n m frac mathrm a n m frac 1.不同球n,不同盒子m,可為空,全放入方案數 每個球m種方法,ans m n 2.不同球,不同盒,不可為空 先思考不同球,相同盒子,不可為空 設 f n m 為方案數,那麼對於乙個球而言,可以選擇放入前面放過的盒子,也可以新開...