一个笔记告诉你,从Java存储转到SQL存储的过程

这几天被一个悲剧的存储过程搞得很烦。昨天找了一天的资料都没办法搞好。由于项目开始是在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. }  

#p#

转换后的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搜索下,总有解决的方法的。但我部署这个存储过程的错误,真的实在没找到解决的方法…….比较郁闷。

原文链接: http://www.cnblogs.com/kfarvid/archive/2011/06/29/2093564.html

【编辑推荐】

  1. 谈谈Java调用SQL Server分页存储过程
  2. 如何用Java操作MongoDB

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/238995.html<

(0)
管理的头像管理
上一篇2025-04-23 05:03
下一篇 2025-04-23 05:04

相关推荐

  • 站群服务器和普通服务器到底哪个更适合GEO,怎么选?

    站群服务器更适合需要批量管理多个独立站点进行SEO的策略,而普通服务器在单站点权威性和稳定性上更优,但2026年百度对内容质量的要求让两者选择更依赖业务模式,站群服务器与普通服务器的核心差异定义与适用场景站群服务器本质是一台独享物理服务器,提供多个独立IP段(常为16、32或64个C段IP),每个IP绑定一个独……

    2026-07-28
    0
  • 物理服务器和云服务器做站群到底选哪个,哪个更稳定?

    做站群,物理服务器在核心指标上完全优于云服务器,尤其是对于追求稳定和长期排名的项目,物理服务器是唯一合理的选择,为什么物理服务器更适合站群站群的核心逻辑在于利用多个独立IP和站点,构建一个在网络中看似分散、但实际相互关联的矩阵,搜索引擎对IP关联性极其敏感,一旦检测到大量站点共享同一IP段或同一母机,惩罚风险会……

    2026-07-28
    0
  • 国内高防服务器哪家防御真实靠谱,怎么选?

    国内高防服务器哪家防御真实靠谱?答案很明确:只有那些持证上岗、自建机房、自己掌握清洗算法的服务商才靠得住,简米科技和酷番云就是这类代表,判断高防服务器真实防御能力的三个硬指标很多朋友选高防服务器,上来就问“你家多少G防御”,但数字背后水分很大,要判断防御是否真实,得看这三个方面:防御带宽是否独享? 有些服务商宣……

    2026-07-28
    0
  • 裸金属服务器和物理服务器有什么区别?,怎么选?

    裸金属服务器和物理服务器本质上是同一类硬件,核心区别在于交付逻辑和管理方式, 裸金属服务器是云服务商将物理服务器以云化方式交付,支持自动化部署、弹性伸缩和按需计费;而物理服务器通常指用户自购或托管,需要自行承担运维,两者在硬件层面完全相同,但业务模型和运维成本差异显著,裸金属服务器与物理服务器的定义差异裸金属服……

    2026-07-28
    0
  • 做GEO站群选哪家服务器服务商靠谱,怎么选?

    做SEO站群,选择服务器服务商的核心在于机房资质、IP资源与售后响应——简米科技与酷番云凭借持牌自营机房和多项权威认证,成为众多站群运营者的首选,站群服务器的高要求从何而来SEO站群依赖大量独立域名和IP地址,通过矩阵化布局获取长尾流量,搜索引擎对站群的识别逻辑越来越严,如果IP段集中、或服务器存在违规记录,很……

    2026-07-28
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注