Total Pageviews

2014/09/30

2014/09 南投

溪頭漢光樓

大學池


溪頭天空步道




竹山紫南宮



2014/09/25

[閱讀筆記] 漫步華爾街

  1. 股價過去的波動不能用來準確預測未來的走勢,因為股市沒有記憶
  2. 股價循環就和賭徒的好壞運一樣,沒有週期可言
  3. 股價波動的歷史,並不能提供有用的資訊,讓投資大眾在管理投資組合時,能持續表現得比長期持有更好
  4. 設定停損點來做買賣,在考慮高額佣金後,使用這套辦法買個股或股票指數,並不一定能勝過簡單的買進持有策略。因此個別投資者最好避免使用這套辦法,以及避開推薦他的經紀人
  5. 頻繁進出股市的代價是,你的交易手續費會大增,計入手續費成本後,投資人所獲反不如簡單地買進並持有多種股票
  6. 技術分析的信號和接下來的股價表現間沒有關係。如果你跟著信號買進賣出,扣掉手續費,報酬仍不比買進持有好
  7. 籃球選手上一次射進籃框與下一次射進籃框的無關,其影響的是球員的『預期』,不是『表現』。股市情況亦然,昨日上漲,所以預期今日也會上漲,過去表現良好,所以預期未來也會表現良好
  8. 相信股市大師預言的人,必定抱憾而終
  9. 股市的行為是隨機漫步的,他就像一個醉漢,在空曠的地面上顢頇行走,他是非理性的,他是不可預測的
  10. 證券分析師無法預測長期持續的成長,因為這根本不存在
  11. 無論是穩定的公共事業,或是隨景氣循環起伏的電子公司,沒有一個產業是容易預測的
  12. 證券分析師平均每年錯誤率為31.3%,代表其在預測時,面對著極大的困難。投資人進行投資決策時,如果盲從這些預測,最後往往希望落空
  13. 影響分析師預測的五大因素:ㄧ、隨機事件的影響;二、創意的會計程序創造令人存疑的盈餘;三、分析師能力不足;四、最好的分析師往往轉任銷售部門或擔任投資組合的管理;五、在擁有大量投資銀行業務的公司裡,分析師面對利益衝突的困境
  14. 公司的損益表好比三點式泳裝,露出來的部分有趣,遮住的地方更重要
  15. 世俗的智慧告訴我們,隨俗而失敗,比不隨俗而成功,更能得到讚美
  16. 投資人購買共同基金的獲利,並不比買進並持有沒有管理的廣泛股票指數好
  17. 共同基金以往的良好績效不能用來推測其未來績效。決定基金績效排名的一項重要因素,仍然是我們的老朋友-運氣
  18. 宣布股票分割不能帶來有用的新資訊,雖然宣布股票分割的公司其股價在宣布的前一段時間就上漲了,宣布後的相關表現卻和市場其他股票沒什麼兩樣。蛋糕不會因為多切幾塊而變大
  19. 股價的變動非常快速,快到沒有人每次都能迅速的從中獲利。如新聞的發生是隨機的,無法預測的,不論是研讀過去的技術資料或基本面資料,都沒有幫助
  20. 股票的價值取決於未來的成長幅度和持續時間,但是要估計它們非常困難
  21. 如果過去股價對於預測未來股價沒什麼用,就不必採用任何技術分析規則來選擇買賣時間點。簡單的買進並長期持有,並不亞於任何技術分析策略
  22. 市場經常反應過度,因此最好遠離眼前時髦的股票,專注於購買那些目前失寵的股票
  23. 尋找價值的投資人,要選擇本益比低、股價與帳面價值比低的股票。價值是基於目前的現實而非未來
  24. 股價與帳面價值比低的股票,未來報酬通常較高
  25. 選擇低本益比的股票比較好,如果成長實現,將帶來加倍利潤;若成長失敗,損失也有限
  26. 股票是衡量機制,不是投票機制
  27. 購買可展期的定期保險,你可以不斷更新保單而不必重新體檢。所謂「遞減」的定期保險是,保單更新時保額可逐次降低,因為隨著時間逝去,需要的保險會跟著遞減
  28. 決定股票報酬三因素:購買時的股利報酬率、盈餘成長率、本益比的改變
  29. 債券的報酬決定於購買時債券到期日的報酬率、利率的改變對債券價格的影響
  30. 平均成本投資法是指在一段很長的時間中,每隔一段時間已一定的金額購買投資標的,如此可以大大減低股票投資風險,因為不會發生所有股票都在最高點的情形
  31. 投資普通股票和債券的持有期越長,風險就越低,但是你得有耐性忍受過程中,投資價值逐年波動的情形
  32. S&P 500指數的表現,長期優於共同基金與機構投資人的平均績效。成長型和價值型共同基金能勝過股票指數的,屈指可數
  33. 四項成功選股原則:只購買至少維持五年盈餘成長超過平均的股票、不購買股價高於合理價值的股票、購買有故事題材的股票、盡可能減少進出
  34. 事實上,少數表現超群、打敗超群的人,其成功有99%可能來自運氣,雖然人們自吹自捧自己的行動,但是那多半來自機運,較少來自偉大的構想



2014/09/21

如何知道債券配息的金額是否來自本金


當我們在看一些基金或債券的資訊的時候,常會看到類似這樣的警語:本基金主要係投資於非投資等級之高風險債券且配息來源可能為本金

有看到這句警語的話,就要想一下,每個月配給我們的現金,是不是從我們的本金拿出來的,如果是的話,就要考慮一下了,那我們要怎麼知道配給我們的現金有沒有從本金拿出來呢?當他的宣傳廣告宣稱有5%年化報酬率,是不是真的有5%呢?

我們分別會需要四個資訊:年化配息率、可分配淨利益佔配息比率、本金佔配息比率以及還原配息率,以下會以聯博全球高收益債券基金AT股當做範例

1. 年化配息率
年化配息率 = 每單位配息金額 / 淨值 * 12
鉅亨網得來的資訊,每單位配息金額為0.0213,淨值為4.67


所以,年化配息率為

2, 3 可分配淨利益佔配息比率、本金佔配息比率
先到聯博的網站找出此檔基金

點進去該檔基金後,滑鼠往下滾,可以找到配息組成詳情

打開pdf後可以看到可分配淨利益佔配息比率、本金佔配息比率


 4. 還原配息率
查到可分配淨利益佔配息比率、本金佔配息比率以後,可以得知其報酬率名符其實,因為本金佔配息比率是0%,所以還原配息率=年化配息率*可分配淨利益佔配息比率還是5.47%


如果用另外一檔房貸收益基金AT股,來看從其每單位分配金額除以淨值,可以得出他的年化配息率是4.99%,但是實際上本金佔配息比例高達51%,所以經過還原以後,實際上的配息率只有2.45%





2014/09/07

Warren Buffett's 23 Most Brilliant Insights About Investing

挺不錯的投資建議
  1. Buying a stock is about more than just the price. 
  2. You don't have to be a genius to invest well.
  3. But, master the basics. 
  4. Don't buy a stock just because everyone hates it. 
  5. Bad things aren't obvious when times are good.
  6. Always be liquid.
  7. The best time to buy a company is when it's in trouble. 
  8. Stocks have always come out of crises. 
  9. Don't be fooled by that Cinderella feeling you get from great returns.
  10. Think long-term. 
  11. Forever is a good holding period. 
  12. Buy businesses that can be run by idiots. 
  13. Be greedy when others are fearful.
  14. You don't have to move at every opportunity.
  15. Ignore politics and macroeconomics when picking stocks.
  16. The more you trade, the more you underperform. 
  17. Price and value are not the same. 
  18. There are no bonus points for complicated investments. 
  19. A good businessperson makes a good investor.
  20. Higher taxes aren't a dealbreaker.
  21. Companies that don't change can be great investments.
  22. Time will tell.
  23. This is the most important thing. "Rule No. 1: never lose money; rule No. 2: don't forget rule No. 1"

發現最近看的幾本書,漸漸歸納出一些原則
  • 要正確預測未來股價、營收成長是很難的,所以股價長跌勢不可預測的,這就是統計學家或經濟學家所提出的隨機漫步(random walk)
  • 投資的原則越簡單越好
  • 股價不代表其真實價值,運用本益比來協助判斷
  • 不要購買股價高過其價值的股票
  • How to Value a Business, and How to Think About Market Prices是兩個最基本且重要的課題
  • 長期持有的報酬率,遠大於一直殺進殺出的投資人
  • 找個笨蛋都能會經營的產業
  • 汰弱留強,好的股票繼續持有,不好的股票就賣掉
  • 長期來說,股市報酬率會是正數
  • 危機入市
  • 不要跟著群眾一窩蜂,在人們恐懼時貪婪,在人們貪婪時恐懼

http://www.businessinsider.com/warren-buffetts-investing-quotes-2014-8?op=1


2014/09/06

A good web site to learn AngularJS


If we would like to learn AngularJS, you can go to here, http://jsbin.com/, to learn. You just need a web browser, do not need to have any IDE(Integrated Development Environment) tools.

Here has a quick start.
1. Go to http://jsbin.com/

2. Click "Add Library"


3. Choose "Angular 1.2.14 stable"


 4. It will import "angular.min.js" automatically

5. Place "ng-app" directive in html tag 

6. create a input text for typing name

7. Check output preivew

8. Design the welcome message as user type in name

9. Demo



2014/09/05

SQL Query Order of Operations

Problem
Here is the select SQL statement:
SELECT YEAR,
       PERIOD,
       NVL(YEAR_PERIOD, ' ') AS YEAR_PERIOD, --年度+期別
       START_DATE, --日期
       NVL(AMT1, 0) AS AMT1, --舉借數額 -國庫券(1)
       NVL(AMT2, 0) AS AMT2,  --舉借數額 -短期借款(2)
       NVL(AMT3, 0) AS AMT3,  --償還數額-國庫券(3)
       NVL(AMT4, 0) AS AMT4 --償還數額-短期借款(4)
FROM FMS435FB
WHERE START_DATE BETWEEN :LAST_YEAR||'1201' AND :LAST_YEAR||'1231'
ORDER BY START_DATE DESC , PERIOD DESC, YEAR_PERIOD DESC
And I would to get the first record from the result set.

Therefore, I add rownum=1 in my where clause. 
Owning to I need to do union with another select statement, so I move it into subquery as bellows:
SELECT *
FROM
  (SELECT YEAR,
          PERIOD,
          NVL(YEAR_PERIOD, ' ') AS YEAR_PERIOD, --年度+期別
          START_DATE,  --日期
          NVL(AMT1, 0) AS AMT1, --舉借數額 -國庫券(1)
          NVL(AMT2, 0) AS AMT2, --舉借數額 -短期借款(2)
          NVL(AMT3, 0) AS AMT3, --償還數額-國庫券(3)
          NVL(AMT4, 0) AS AMT4 --償還數額-短期借款(4)
   FROM FMS435FB
   WHERE START_DATE BETWEEN :LAST_YEAR||'1201' AND :LAST_YEAR||'1231' AND ROWNUM=1
   ORDER BY START_DATE DESC , PERIOD DESC, YEAR_PERIOD DESC)
UNION ALL .....
But I get this record!

Root Cause
This unexpected result result from the SQL query order of operations, the order is:
FROM clause --> WHERE clause --> GROUP BY clause --> HAVING clause --> SELECT clause -->ORDER BY clause

If we marked rownum=1 and order by cluase
SELECT *
FROM
  (SELECT YEAR,
          PERIOD,
          NVL(YEAR_PERIOD, ' ') AS YEAR_PERIOD, --年度+期別
          START_DATE, --日期
          NVL(AMT1, 0) AS AMT1, --舉借數額 -國庫券(1)
          NVL(AMT2, 0) AS AMT2, --舉借數額 -短期借款(2)
          NVL(AMT3, 0) AS AMT3, --償還數額-國庫券(3)
          NVL(AMT4, 0) AS AMT4 --償還數額-短期借款(4)
   FROM FMS435FB
   WHERE START_DATE BETWEEN :LAST_YEAR||'1201' AND :LAST_YEAR||'1231'-- AND ROWNUM=1
 --ORDER BY START_DATE DESC , PERIOD DESC, YEAR_PERIOD DESC
 )
UNION ALL .....
We can find the first record is '1021226' not '1021227', if we marked rownum=1 and order by cluase. Owing the query order operation is from --> where --> select --> order by, 'rownum=1' have already get the first record before order by. So it's the reason why we get the unexpected result.

Solution
We need to get the result which had already been sorted, and apply rownum=1 to get the first record.
SELECT *
FROM
  (SELECT YEAR,
          PERIOD,
          NVL(YEAR_PERIOD, ' ') AS YEAR_PERIOD, --年度+期別
          START_DATE, --日期
          NVL(AMT1, 0) AS AMT1, --舉借數額 -國庫券(1)
          NVL(AMT2, 0) AS AMT2, --舉借數額 -短期借款(2)
          NVL(AMT3, 0) AS AMT3, --償還數額-國庫券(3)
          NVL(AMT4, 0) AS AMT4 --償還數額-短期借款(4)
   FROM FMS435FB
   WHERE START_DATE BETWEEN :LAST_YEAR||'1201' AND :LAST_YEAR||'1231'
   ORDER BY START_DATE DESC , PERIOD DESC, YEAR_PERIOD DESC)
WHERE ROWNUM=1
UNION ALL .....


Reference
[1] http://www.bennadel.com/blog/70-sql-query-order-of-operations.htm

2014/08/28

[Oracle] How to Create Before Insert Trigger

Requirement
Here has one of my table schema, and the first column, SEQ_NO, will be assigned serial number which value will be get from SE_FMS_CF0006 sequence.

I hope I do not need get the sequence value manually and assign to SEQ_NO column manually.

Column
Type
Size
Nulls
Default
Comments
SEQ_NO
number
20
流水號SELECT SE_FMS_CF0006.NEXTVAL FROM DUAL
AGE
varchar2
7
 √ 
null
資料提供機構代碼
FILE_TYPE
varchar2
8
 √ 
null
傳輸檔案識別
PDATE
varchar2
7
資料日期
FYR
varchar2
3
 √ 
null
會計年度
ACC
varchar2
11
科目代碼
ACC_APPENDIX
varchar2
3
科目代碼附加碼
AMOUNT
number
15,2
 √ 
0
金額
UPDATE_DATE
timestamp(6)
11,6
 √ 
now
更新日期
USER_ID
varchar2
20
 √ 
null
異動者


Solution
We can make good use of trigger to fulfill this requirement, you can check the before insert trigger. 
As you do insert, you can skip SEQ_NO, this trigger will get the serial number before you do insert.
CREATE OR REPLACE TRIGGER AP_PSR.TR_BI_CF0006  
  BEFORE INSERT ON AP_PSR.CF0006  FOR EACH ROW  
 BEGIN  
  IF :NEW.SEQ_NO IS NULL THEN  
   SELECT SE_FMS_CF0006.NEXTVAL INTO :NEW.SEQ_NO FROM DUAL;  
  END IF;  
 END;  

Demo
Assume I would like to execute the insert statement, I only provide values to mandatory columns except SEQ_NO.

INSERT INTO cf0006(pdate, acc, acc_appendix)
VALUES('1030401', '123', '123');
Then execute the select statement:
SELECT * FROM cf0006;

See.... I did not assign any value to SEQ_NO, its value assigned by TR_BI_CF0006  trigger automatically.


Reference
[1] http://www.techonthenet.com/oracle/triggers/before_insert.php

2014/08/27

ORA-17004 : Invalid Column Type

Problem
I am using JPA(Java Persistence API) as my persistence tier technology to write data into Oracle database. Here is the database schema for the targeted table:
Column
Type
Size
Nulls
Default
Comments
EXE_ID
number
20
執行ID, Calendar.getInstance().getTimeInMillis()
FUNCTION_ID
varchar2
20
功能代號
MESSAGE
nvarchar2
2000
 V 
null
執行訊息
EXECUTE_TYPE
varchar2
1
V
null
C:CRON JOB, M: MANNUAL, U:Upload
USER_ID
varchar2
20
 V 
null
批次執行時,帶功能名稱,手動執行時,帶執行人USER_ID
UPDATE_DATE_TIME
timestamp(6)
11,6
 V 
now
執行時間
FILE_NAME
varchar2
40
 V 
null
檔案名稱

Here is the code snippet:
1:    public void writeLog(Boolean isSuccessful, String funId, String exceptionMsg) {  
2:      try {  
3:        StringBuilder sql = new StringBuilder();  
4:        sql.append("INSERT INTO FMS900FA(EXE_ID, FUNCTION_ID, MESSAGE, EXECUTE_TYPE, USER_ID, FILE_NAME)");  
5:        sql.append(" VALUES(:EXE_ID, :FUNCTION_ID, :MESSAGE, :EXECUTE_TYPE, :USER_ID, :FILE_NAME)");  
6:        Map<String, Object> params = new HashMap<String, Object>();  
7:        params.put("EXE_ID", BigInteger.valueOf(Calendar.getInstance().getTimeInMillis()));  
8:        params.put("FUNCTION_ID", funId);  
9:        if (isSuccessful) {  
10:          params.put("MESSAGE", "執行成功");  
11:        } else {  
12:          params.put("MESSAGE", exceptionMsg);  
13:        }  
14:        params.put("EXECUTE_TYPE", "C");  
15:        params.put("USER_ID", "ADMIN");  
16:        params.put("FILE_NAME", "NA");  
17:        sqlExecutor.insert(sql, params);  
18:      } catch(Exception e) {  
19:        throw e;  
20:      }  
21:    }   

But program throw SQLException
1:  Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [INSERT INTO FMS900FA(EXE_ID, FUNCTION_ID, MESSAGE, EXECUTE_TYPE, USER_ID, FILE_NAME)  VALUES(?, ?, ?, ?, ?, ?) ]; SQL state [99999]; error code [17004]; invalid column type; nested exception is java.sql.SQLException: invalid column type  
2:       at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
3:       at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
4:       at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
5:       at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:660) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
6:       at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:909) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
7:       at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:933) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
8:       at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:313) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
9:       at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.update(NamedParameterJdbcTemplate.java:318) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
10:       at com.cht.commons.persistence.query.SqlExecutor.execute(SqlExecutor.java:97) ~[cht-commons-persistence-0.1.0-SNAPSHOT.jar!/:0.1.0-SNAPSHOT]  
11:       at com.cht.commons.persistence.query.SqlExecutor.insert(SqlExecutor.java:157) ~[cht-commons-persistence-0.1.0-SNAPSHOT.jar!/:0.1.0-SNAPSHOT]  
12:       at com.cht.commons.persistence.query.SqlExecutor.insert(SqlExecutor.java:146) ~[cht-commons-persistence-0.1.0-SNAPSHOT.jar!/:0.1.0-SNAPSHOT]  
13:       at gov.nta.fms.service.FmsBatchLog.writeLog(FmsBatchLog.java:139) ~[fms-service-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]  
14:       at gov.nta.fms.service.Fms435xService.initFms435fa(Fms435xService.java:228) ~[fms-service-1.0.0-SNAPSHOT.jar:1.0.0-SNAPSHOT]  
15:       at gov.nta.fms.service.Fms435xService$$FastClassBySpringCGLIB$$75f6a95.invoke() ~[na:na]  
16:       at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
17:       at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:711) ~[spring-aop-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
18:       at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
19:       at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98) ~[spring-tx-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
20:       at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:262) ~[spring-tx-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
21:       at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95) ~[spring-tx-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
22:       at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
23:       at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58) ~[spring-aop-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
24:       ... 111 common frames omitted  
25:  Caused by: java.sql.SQLException: invalid column type  
26:       at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8761) ~[na:na]  
27:       at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8259) ~[na:na]  
28:       at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9012) ~[na:na]  
29:       at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:8993) ~[na:na]  
30:       at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:230) ~[na:na]  
31:       at org.jboss.jca.adapters.jdbc.WrappedPreparedStatement.setObject(WrappedPreparedStatement.java:986) ~[na:na]  
32:       at org.springframework.jdbc.core.StatementCreatorUtils.setValue(StatementCreatorUtils.java:402) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
33:       at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValueInternal(StatementCreatorUtils.java:235) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
34:       at org.springframework.jdbc.core.StatementCreatorUtils.setParameterValue(StatementCreatorUtils.java:150) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
35:       at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.setValues(PreparedStatementCreatorFactory.java:300) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
36:       at org.springframework.jdbc.core.PreparedStatementCreatorFactory$PreparedStatementCreatorImpl.createPreparedStatement(PreparedStatementCreatorFactory.java:252) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
37:       at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:638) ~[spring-jdbc-4.0.3.RELEASE.jar!/:4.0.3.RELEASE]  
38:       ... 129 common frames omitted  

How to solve it?
This SQLException, ORA-17004 : Invalid Column Type, results from EXE_ID this column.

We use BigInteger originally, but fail to do insert. As we change to use BigDecimal, it's working fine now. But the root cause is still unknown.
1:    public void writeLog(Boolean isSuccessful, String funId, String exceptionMsg) {  
2:      try {  
3:        StringBuilder sql = new StringBuilder();  
4:        sql.append("INSERT INTO FMS900FA(EXE_ID, FUNCTION_ID, MESSAGE, EXECUTE_TYPE, USER_ID, FILE_NAME)");  
5:        sql.append(" VALUES(:EXE_ID, :FUNCTION_ID, :MESSAGE, :EXECUTE_TYPE, :USER_ID, :FILE_NAME)");  
6:        Map<String, Object> params = new HashMap<String, Object>();  
7:        params.put("EXE_ID", new BigDecimal(Calendar.getInstance().getTimeInMillis()));  
8:        params.put("FUNCTION_ID", funId);  
9:        if (isSuccessful) {  
10:          params.put("MESSAGE", "執行成功");  
11:        } else {  
12:          params.put("MESSAGE", exceptionMsg);  
13:        }  
14:        params.put("EXECUTE_TYPE", "C");  
15:        params.put("USER_ID", "ADMIN");  
16:        params.put("FILE_NAME", "NA");  
17:        sqlExecutor.insert(sql, params);  
18:      } catch(Exception e) {  
19:        throw e;  
20:      }  
21: