程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 一個筆記告訴你,從Java存儲轉到SQL存儲的過程

一個筆記告訴你,從Java存儲轉到SQL存儲的過程

編輯:DB2教程

這幾天被一個悲劇的存儲過程搞得很煩。昨天找了一天的資料都沒辦法搞好。由於項目開始是在DB2的開發中心,用Java寫的存儲過程。由於客戶升級的需要,數據庫遷移到更高版本的數據庫中去了,遷移後,這個存儲過程就用不了了。於是我打開DB2的開發中心,打開該存儲過程的項目,打算部署到新的DB2上,無論怎麼部署,始終都提示下面的錯誤:

  1. Call SQLJ.DB2_INSTALL_JAR (<<C:\Documents and Settings\jinghua\Application Data\IBM\DB2\DC\項目\bld1309245830936\SQL110528115458880.jar>>, 'GDZJ.SQL110528115458880', 0)  
  2. [IBM][CLI Driver][DB2/AIX64] SQL4304N 具有特定名稱 "SQL110628152507130" 的 Java 存儲過程或用戶定義的函數 "sqlejReadJar"不能裝入 Java 類 "COM/ibm/db2/app/sqlejProcs",原因碼為 "5"。  SQLSTATE=42724 

在google中無論搜索中文還是英文的資料,都找不到解決的方案,於是,把這腦殘的問題,從Java中轉換到db2的sql中去。下面先看看該存儲過程的代碼:

  1. /**  
  2.  * SQLJ 存儲過程 GDZJ.BaseCodeGen  
  3.  * @param enprName 企業名稱  
  4.  * @param enprAddr 企業地址  
  5.  * @param enprLeader 法人  
  6.  * @param enprPhone 聯系電話  
  7.  * @param baseCode 返回的基准碼  
  8.  */ 
  9. package com.Excellence.basecodesrv;  
  10.  
  11. import Java.io.FileWriter;  
  12. import Java.io.PrintWriter;  
  13.  
  14. import Java.sql.*;           // JDBC 類  
  15. import Java.util.Map;  
  16. import Java.util.HashMap;  
  17. import Java.util.Date;  
  18. import sqlj.runtime.*;  
  19. import sqlj.runtime.ref.*;  
  20.  
  21. #sql context SPContext;  
  22. #sql iterator BaseCodeGen_Cursor1 ( String curBaseCode );  
  23. #sql iterator BaseCodeGen_Cursor2 ( String curBaseCode );  
  24.  
  25. public class BaseCodeGen  
  26. {  
  27.     /**  
  28.      * @param  enprName  
  29.      * @param  enprAddr  
  30.      * @param  enprLeader  
  31.      * @param  enprPhone  
  32.      * @param  baseCode  
  33.      * @exception  SQLException  
  34.      * @exception  Exception  
  35.      */ 
  36.     public static void baseCodeGen ( String enprName,  
  37.                                      String enprAddr,  
  38.                                      String enprLeader,  
  39.                                      String enprPhone,  
  40.                                      String[] baseCode ) throws SQLException, Exception  
  41.     {  
  42.         BaseCodeGen_Cursor1 cursor1 = null;  
  43.         BaseCodeGen_Cursor2 cursor2 = null;  
  44.         SPContext ctx = null;  
  45.         try 
  46.         {  
  47.             if(enprName==null || enprName.trim().equals("")){  
  48.                 // 設置返回參數  
  49.                 baseCode[0] = null;  
  50.                 return;  
  51.             }  
  52.             ctx = new SPContext( "jdbc:default:connection"false );  
  53.  
  54.             #sql [ctx] cursor1 =  
  55.             {  
  56.                 select max(enpr_basecode) as curBaseCode from T_PUB_BASECODE where enpr_name like concat(concat('%',:enprName),'%')  
  57.             };  
  58.             // 用來存取結果  
  59.              //ResultSet rs1 = cursor1.getResultSet();  
  60.              String curBaseCode = "";  
  61.              while (cursor1.next())  
  62.              {  
  63.                 curBaseCode = cursor1.curBaseCode();  
  64.              }  
  65.             // 關閉打開資源  
  66.             if (cursor1 != null) cursor1.close();  
  67.  
  68.             if(curBaseCode!=null && !curBaseCode.trim().equals("")){  
  69.                 // 設置返回參數  
  70.                 baseCode[0] = curBaseCode;  
  71.                 return;  
  72.             }else{  
  73.                 #sql [ctx] cursor2 =  
  74.                     {  
  75.                         select max(enpr_basecode) as curBaseCode from T_PUB_BASECODE  
  76.                     };  
  77.                  while (cursor2.next())  
  78.                  {  
  79.                     curBaseCode = cursor2.curBaseCode();  
  80.                 }  
  81.                     // 關閉打開資源  
  82.                 if (cursor2 != null) cursor2.close();  
  83.             }  
  84.  
  85.             //權重  
  86.             Map weight = new HashMap();  
  87.             weight.put(new Integer("3"), new Integer("9"));  
  88.             weight.put(new Integer("4"), new Integer("10"));  
  89.             weight.put(new Integer("5"), new Integer("5"));  
  90.             weight.put(new Integer("6"), new Integer("8"));  
  91.             weight.put(new Integer("7"), new Integer("4"));  
  92.             weight.put(new Integer("8"), new Integer("2"));  
  93.  
  94.             String domain = "GZ"// 主體碼  
  95.             String entityCode = ""// 本體碼  
  96.             String checkCode = ""// 校驗碼  
  97.             String rtnBaseCode = ""// 返回的基准碼  
  98.  
  99.             entityCode = curBaseCode==null?"333333":curBaseCode.substring(2,8);  
  100.             if (entityCode.equals("ZZZZZZ")) {  
  101.                 throw new Exception("本體碼分配已經用完,無法再生成新的企業基准碼!");  
  102.             }  
  103.               
  104.             // 本體碼 begin  
  105.             String newEntityCode = "";  
  106.             char c = '0';  
  107.             for(int i=5; i>=0; --i){              
  108.                 c = entityCode.charAt(i);  
  109.  
  110.                 if(c == '9'){  
  111.                     c =  'A';  
  112.                 }else if(c == 'Z'){  
  113.                     c =  '0';  
  114.                 }else{  
  115.                     ++c;  
  116.                 }  
  117.  
  118.                 newEntityCode = c+newEntityCode;  
  119.                 if(c<'Z' && c!='0'){  
  120.                     newEntityCode = entityCode.substring(0,i)+newEntityCode;  
  121.                     break;  
  122.                 }  
  123.             }  
  124.             entityCode = newEntityCode;  
  125.             // 本體碼 end  
  126.  
  127.             // 校驗碼 begin  
  128.             int charWeight = 0// 本體碼‘位’的權重  
  129.             int entityCharNum = 0// 本體碼‘位’的數值  
  130.             int sum = 0// 本體碼‘位’的權重 與 本體碼‘位’的數值 的乘積  
  131.             char sglChar = '0';  
  132.             for(int i=0; i<6; i++){  
  133.                 sglChar = entityCode.charAt(i);  
  134.                 if(sglChar > '9'){  
  135.                     entityCharNum = sglChar - 55;  
  136.                 }else{  
  137.                     entityCharNum = sglChar - 48;  
  138.                 }              
  139.                 charWeight = ((Integer)weight.get(new Integer(i+3))).intValue();  
  140.                 sum += entityCharNum*charWeight;  
  141.             }  
  142.               
  143.             int cc = 11 - sum%11;      
  144.               
  145.             switch(cc){          
  146.                 case 10:  
  147.                     checkCode = "X";  
  148.                     break;  
  149.                 case 11:  
  150.                     checkCode = "0";  
  151.                     break;  
  152.                 default :  
  153.                     checkCode = String.valueOf(cc);  
  154.                     break;  
  155.             }  
  156.             // 校驗碼 end  
  157.  
  158.             rtnBaseCode = domain+entityCode+checkCode;  
  159.  
  160.             Date genTime = new Java.sql.Date(new Date().getTime());  
  161.             Date giveTime = new Java.sql.Date(new Date().getTime());  
  162.             #sql  
  163.             {  
  164.                 insert into T_PUB_BASECODE(enpr_name,charger,address,phone,enpr_basecode,gen_bc_time,give_bc_time) values(:enprName,:enprLeader,:enprAddr,:enprPhone,:rtnBaseCode,:genTime,:giveTime)  
  165.             };  
  166.  
  167.             // 設置返回參數  
  168.             baseCode[0] = rtnBaseCode;  
  169.         }  
  170.         catch (Exception e)  
  171.         {  
  172.             // 關閉打開資源  
  173.             try 
  174.             {  
  175.                 if (cursor1 != null) cursor1.close();  
  176.                 if (cursor2 != null) cursor2.close();  
  177.                 if (ctx != null) ctx.close();  
  178.             } catch (SQLException e2) { /* 忽略 */ };  
  179.  
  180.             /*  
  181.             try{  
  182.                 PrintWriter pwx = new PrintWriter(new FileWriter("c:/db2ps.txt"),true);  
  183.                 e.printStackTrace(pwx);  
  184.             }catch(Exception e3){ }  
  185.             */           
  186.  
  187.             throw e;  
  188.         }  
  189.     }  
  190.       
  191. }  
  192. 轉換後的DB2存儲過程為:

    1. -- Start of generated script for server226-DB2-GDZJ (gdzj)  
    2. --  Jun-29-2011 at 10:51:42  
    3.  
    4. SET SCHEMA GDZJ    ;  
    5.  
    6. SET CURRENT PATH = "SYSIBM","SYSFUN","SYSPROC","GDZJ";  
    7. drop PROCEDURE GDZJ.BASECODEGEN_ZGW;  
    8. CREATE PROCEDURE GDZJ.BASECODEGEN_ZGW  
    9.  (IN ENPRNAME VARCHAR(256),   
    10.   IN ENPRADDR VARCHAR(256),   
    11.   IN ENPRLEADER VARCHAR(64),   
    12.   IN ENPRPHONE VARCHAR(64),   
    13.   OUT BASECODE VARCHAR(32)  
    14.  )   
    15.   LANGUAGE SQL  
    16.   NOT DETERMINISTIC  
    17.   CALLED ON NULL INPUT  
    18.   MODIFIES SQL DATA  
    19.   INHERIT SPECIAL REGISTERS  
    20.   l1:begin 
    21.   declare curBaseCode varchar(16) default '';  
    22.   declare domain varchar(16) default 'GZ';--主體碼  
    23.   declare entityCode varchar(16) default '';-- 本體碼  
    24.   declare checkCode varchar(16) default '';-- 校驗碼  
    25.   declare rtnBaseCode  varchar(16) default '';-- 返回的基准碼  
    26.   declare newEntityCode varchar(16) default '';  
    27.   declare V_COUNT int default 0;  
    28.   declare V_INDEX int default 0;  
    29.   declare cc int default 0;  
    30.   declare c char(1) default '0';  
    31.     
    32.   declare charWeight int default 0; -- 本體碼‘位’的權重  
    33.   declare entityCharNum int default 0; -- 本體碼‘位’的數值  
    34.   declare sum int default 0; -- 本體碼‘位’的權重 與 本體碼‘位’的數值 的乘積  
    35.   declare sglChar char(1) default '0';  
    36.         
    37.   if ENPRNAME is null or rtrim(ENPRNAME)='' then 
    38.        set BASECODE = null;  
    39.      return;  
    40.   end if;  
    41.   set curBaseCode=(select max(enpr_basecode) from T_PUB_BASECODE where enpr_name like '%'||ENPRNAME||'%' );  
    42.   if curBaseCode is not null and rtrim(curBaseCode)!='' then 
    43.     set BASECODE =curBaseCode;    
    44.     return;  
    45.   else 
    46.     set curBaseCode=(select max(enpr_basecode) from T_PUB_BASECODE);  
    47.   end if;  
    48.   if curBaseCode is null then 
    49.     set entityCode='333333';  
    50.   else 
    51.     set entityCode = SUBSTR(curBaseCode,3,6);  
    52.   end if;  
    53.   if entityCode='ZZZZZZ' then 
    54.      set BASECODE =null;  
    55.      return;  
    56.   end if;  
    57.     
    58.   --本體碼 begin  
    59.   SET V_COUNT = LENGTH(entityCode);  
    60.   set V_INDEX=V_COUNT;  
    61.     
    62. WHILE V_INDEX >0 DO  
    63. set c = SUBSTR(entityCode,V_INDEX,1);  
    64.  
    65. if c = '9' then 
    66.   set c =  'A';  
    67. elseif c='Z' then 
    68.   set c='0';  
    69. else 
    70.   set c=chr(DEC_TO_TEN(HEX(c),16)+1);  
    71. end if;  
    72.  
    73. set newEntityCode=c||newEntityCode;  
    74.  
    75. if c<'Z' and c!='0' then 
    76.   set newEntityCode = SUBSTR(entityCode,1,V_INDEX-1)||newEntityCode;  
    77.   set V_INDEX=0;  
    78. end if;  
    79. set V_INDEX=V_INDEX-1;  
    80.  
    81. END WHILE;  
    82. set entityCode = newEntityCode;  
    83. --本體碼 end  
    84. --校驗碼 begin  
    85.   set V_INDEX=0;  
    86. WHILE V_INDEX<6 DO  
    87.   set sglChar = SUBSTR(entityCode,V_INDEX+1,1);  
    88.   if sglChar>'9' then 
    89.     set entityCharNum=DEC_TO_TEN(HEX(sglChar),16)-55;  
    90.   else 
    91.     set entityCharNum=DEC_TO_TEN(HEX(sglChar),16)-48;  
    92.   end if;  
    93.   --設置權重值  
    94.   case V_INDEX  
    95.   when 0 then set charWeight=9;  
    96.   when 1 then set charWeight=10;  
    97.   when 2 then set charWeight=5;  
    98.   when 3 then set charWeight=8;  
    99.   when 4 then set charWeight=4;  
    100.   when 5 then set charWeight=2;  
    101.   else 
    102.     set charWeight=0;  
    103.   end case;  
    104.   set sum=sum+entityCharNum*charWeight;  
    105.     
    106.   set V_INDEX=V_INDEX+1;  
    107. END WHILE;  
    108.  
    109. set cc=11 - mod(sum,11);      
    110.               
    111. case cc  
    112.   when 10 then set checkCode = 'X';  
    113.   when 11 then set checkCode = '0';  
    114.   else 
    115.     set checkCode = char(cc);  
    116.   end case;  
    117.  
    118. --校驗碼 end  
    119.   set rtnBaseCode = domain||entityCode||checkCode;  
    120.   insert into T_PUB_BASECODE(enpr_name,charger,address,phone,enpr_basecode,gen_bc_time,give_bc_time)   
    121.   values(enprName,enprLeader,enprAddr,enprPhone,rtnBaseCode,current date,current date);  
    122.     
    123.   set BASECODE =rtnBaseCode;  
    124.     
    125. return;  
    126.  
    127. end l1;  
    128. #SYNC 10;  
    129.  
    130.  
    131.  
    132. -- End of generated script for server226-DB2-GDZJ (gdzj) 

    其中,該存儲過程中使用的一個自定義函數:DEC_TO_TEN(16進制轉換成10進制),其代碼如下(該代碼非原創,在網絡上搜索到的):

    1. -- Start of generated script for server226-DB2-GDZJ (gdzj)  
    2. --  Jun-29-2011 at 13:01:54  
    3.  
    4. SET SCHEMA GDZJ    ;  
    5.  
    6. SET CURRENT PATH = "SYSIBM","SYSFUN","SYSPROC","GDZJ";  
    7.  
    8. CREATE FUNCTION GDZJ.DEC_TO_TEN  
    9.  (pStr VARCHAR(25),  
    10.   p_from_base INTEGER 
    11.  )   
    12.   RETURNS INTEGER 
    13.   LANGUAGE SQL  
    14.   NOT DETERMINISTIC  
    15.   READS SQL DATA  
    16.   STATIC DISPATCH  
    17.   CALLED ON NULL INPUT  
    18.   EXTERNAL ACTION 
    19.   INHERIT SPECIAL REGISTERS  
    20.   BEGIN ATOMIC  
    21.     
    22.   DECLARE l_num int default 0;   
    23. DECLARE l_hex varchar(16) default '0123456789ABCDEF';   
    24. DECLARE k int default 1;   
    25. DECLARE kcount int;   
    26. DECLARE posNum int default 0;   
    27.  
    28.  
    29. set kcount = length(pStr);   
    30. WHILE k <=kcount DO   
    31. set posNum = locate(UPPER(SUBSTR(pStr,k,1)),l_hex)-1;   
    32. set l_num = l_num * p_from_base + posNum;   
    33. set k=k+1;   
    34. END WHILE;   
    35. RETURN l_num;  
    36.   END;  
    37. #SYNC 10;  
    38.  
    39.  
    40.  
    41. -- End of generated script for server226-DB2-GDZJ (gdzj) 

    其中,來總結一下經驗:

    1:DB2本身沒有16進制轉換成10進制的函數,得自己搞一個。

    2:DB2的函數用法,如SUBSTR,HEX,char,以及||等的用法,其實,很多Java中有的基本方法,DB2中也有的。

    3:Java中的循環,DB2其實也有的。

    4:能把該java的代碼轉換到DB2中的sql來,主要是由於該存儲過程只是一個字符串的處理,沒涉及到Java中復雜的東西,這才是成功的關鍵。遇到不會的,多上google搜索下,總有解決的方法的。但我部署這個存儲過程的錯誤,真的實在沒找到解決的方法.......比較郁悶。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved