數據庫應用開發中,經常會遇到一些比較複雜的SQL式計算,比如記錄拆分,將按分隔符分隔的一條記錄拆分成多條記錄。SQL在實現時由於數據庫間的差異,會遇到語法支持不足、嵌套多層等問題。而集算器具有豐富的類庫,可以編寫直觀分步的腳本,完成這類計算要簡單許多,下面通過一個例子來看一下集算器的實現方式。
應用程序將用戶一次登陸後的所有操作代碼按逗號分隔,以一條記錄存儲到數據庫用戶操作表user_op中,該表部分數據如下:
LOGTIME USERID OPID
2014/1/3 11:10:12 100001 a,d,h
2014/1/3 9:23:12 100002 a,e,g,p
2014/1/3 10:35:11 100003 a,r,n
現需要將逗號分隔的OPID拆分成多行,如第一條記錄拆分後應爲:
LOGTIME USERID OPID
2014/1/3 11:10:12 100001 a
2014/1/3 11:10:12 100001 d
2014/1/3 11:10:12 100001 h
SQL在實現這類運算時需要藉助遞歸查詢實現,對於遞歸查詢支持不好的數據庫實現起來異常困難,而對遞歸查詢支持不錯的Oracle實現也並不簡單,比如下面的SQL實現語句:
SELECT logtime,userid,REGEXP_SUBSTR(opid,’[^,]+’,1,rn) opid
FROM user_op,(SELECT LEVEL rn FROM DUAL
CONNECT BY LEVEL WHERE REGEXP_SUBSTR(opid,’[^,]+’,1,rn) IS NOT NULL
或者:
select logtime,userid,regexp_substr(opid,’[^,]+’,1,level) opid
from user_op
connect by level and rowid= prior rowid
and prior dbms_random.value is not null
從以上的實現中可以看出SQL實現的複雜性,下面看一下集算器的實現代碼:
其中:
A1=esProc.query(“SELECT LOGTIME,USERID,OPID FROM USER_OP”)
從數據庫中查詢user_op表數據,部分查詢結果如下:
A2= A1.create()
根據A1的序表創建新序表,並複製A1的結構,用於存儲最終結果集。結果如下:
A3=A1.(OPID.array().(A2.record([A1.LOGTIME,A1.USERID,~])))
循環A1序表,拆分OPID字段值,轉爲轉爲序列,並將拆分後結果寫回A2結果集。計算後的A2結果如下:
可以看到在集算器中通過這樣簡單的三行代碼就完成了拆分記錄的計算。另外,集算器可被報表工具或java程序調用,調用的方法也和普通數據庫相似,使用它提供的JDBC接口即可向java主程序返回ResultSet形式的計算結果,具體方法可參考相關文檔。