问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

调用Java存储过程遇到SQL4306N时怎么办

发布网友 发布时间:2022-04-22 09:25

我来回答

2个回答

热心网友 时间:2022-04-09 06:54

本文讲解了在开发Java存储过程时经常会碰到的一个问题及其解决办法。

inginStr,intinStart,intinNum)
throwsException
{
if(inStart<1||inStart>inStr.length()||inNum<=0)outStr="";
if((inStart-1+inNum)>inStr.length())inNum=inStr.length()+1-inS
tart;
outStr=inStr.substring(inStart-1,inStart+inNum-1);
}
}

2.创建存储过程的DDL语句(SpTest.db2):
DROPSPECIFICPROCEDURETESTSUB@
CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE

3.编译并定义Java存储过程:
$javacSpTest.java
$cpSpTest.class~/sqllib/function
$db2connecttosample
DatabaseConnectionInformation
Databaseserver=DB2/60008.2.0
SQLauthorizationID=XXXX
Localdatabasealias=SAMPLE

$db2-td@-vfSpTest.db2
DROPSPECIFICPROCEDURETESTSUB
DB21034EThecommandwasprocessedasanSQLstatementbecauseitwasnota
validCommandLineProcessorcommand.DuringSQLprocessingitreturned:
SQL0204N"XXXX.TESTSUB"isanundefinedname.SQLSTATE=42704

CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE
EXTERNALNAME'SpTest.subString'
DB20000ITheSQLcommandcompletedsuccessfully.

$db2"callsubString(?,'sdafatewfdsa',2,5)"
SQL4306NJavastoredprocereoruser-definedfunction"XXXX.SUBSTRING",
specificname"TESTSUB"couldnotcallJavamethod"subString",signature
"([Ljava/lang/String;Ljava/lang/Strin".SQLSTATE=42724

我们经过检查,发现类名正确、类库也在目录$HOME/sqllib/function下。这时我们集中精力检查程序的签名(Signature)。因为在错误信息中,签名不全,我们要查看$DB2DIAGPATH/db2diag.log文件(其中$DB2DIAGPATH代表数据库管理器配置参数中的DIAGPATH参数)。我们看到完整的签名为:

2005-08-17-14.47.19.569936+480I126072C540LEVEL:Warning
PID:1810588TID:1287PROC:db2fmp(Java)0
INSTANCE:XXXXNODE:000
FUNCTION:DB2UDB,BSUJavasupport,sqlejCallJavaRoutine_dll,probe:150
MESSAGE:JNIGetMethodIDfailed.signature:
DATA#1:Hexmp,42bytes
0x3007A950:285B4C6A6176612F6C616E672F537472([Ljava/lang/Str
0x3007A960:696E673B4C6A6176612F6C616E672F53ing;Ljava/lang/S
0x3007A970:7472696E673B49492956tring;II)V

这是DB2用来查找Java存储过程对应的方法时用的签名(Signature),此时我们再检查一下类文件中SubString方法的签名:
$cd~/sqllib/function
$javap-sSpTest
Thisutilitycanbeusedtoreverseassemblecode.Manyprogramlicense
agreementsdonotpermitreverseassembly.Ifyouarenotthecopyright
ownerofthecodewhichyouwanttoreverseassemble,pleasecheckthe
licenseagreementunderwhichyouacquiredsuchcodetoconfirmwhether
youarepermittedtoperformsuchreverseassembly.

CompiledfromSpTest.java
publicclassSpTestextendsjava.lang.Object{
publicSpTest();
/*()V*/
publicstaticvoidsubString(java.lang.String,java.lang.String,int,int)t
hrowsjava.lang.Exception;
/*(Ljava/lang/String;Ljava/lang/String;II)V*/

我们看到在Java类中的函数签名与DB2查找的函数签名不一致。这就是SQL4306N产生的原因。

第一个参数不一样。根据JNI规范,[Ljava/lang/String是一个String数组。而Ljava/lang/String则是字符串String类型,也就是我们程序源文件中定义的类型。那为什么DB2要查找一个String数组类型的参数呢?通过查找DB2文档,我们发现如下解释(http://publib.boulder.ibm.com/infocenter/db2help/topic/com.ibm.db2.udb.doc/admin/r0008328.htm):
PARAMETERTYPEJAVA
ThismeansthattheprocerewilluseaparameterpassingconventionthatconformstotheJavalanguageandSQLJRoutinesspecification.IN/OUTandOUTparameterswillbepassedassingleentryarraystofacilitatereturningvalues.ThiscanonlybespecifiedwhenLANGUAGEJAVAisused.

我们看到如果创建存储过程时使用了IN/OUT以及OUT参数,DB2会将其解释为一个单项数组,并通过单项数组传递返回值。因此,我们同样需要在Java程序中使用字符串数组来返回我们的结果。

修改后的java源程序如下所示:
importjava.lang.*;
importjava.io.*;
publicclassSpTest
{
publicstaticvoidsubString(String[]outStr,StringinStr,intinStart,intin
Num)
throwsException
{
if(inStart<1||inStart>inStr.length()||inNum<=0)outStr[0]="";
if((inStart-1+inNum)>inStr.length())inNum=inStr.length()+1-inS
tart;
outStr[0]=inStr.substring(inStart-1,inStart+inNum-1);
}
}

此时我们重新编译并创建存储过程,可以看到,它可以正确执行了。
$javacSpTest.java
$cpSpTest.class~/sqllib/function
$db2-td@-vfSpTest.db2
DROPSPECIFICPROCEDURETESTSUB
DB20000ITheSQLcommandcompletedsuccessfully.

CREATEPROCEDUREsubString(OUTOUTSTRINGVARCHAR(500),ININSTRINGVARCHAR(500),I
NINSTARTINT,ININNUMINT)
SPECIFICTESTSUB
DYNAMICRESULTSETS0
DETERMINISTIC
LANGUAGEJAVA
PARAMETERSTYLEJAVA
NODBINFO
FENCED
THREADSAFE
EXTERNALNAME'SpTest.subString'
DB20000ITheSQLcommandcompletedsuccessfully.

$db2"callsubstring(?,'sadfdsafdsaf',2,5)"
Valueofoutputparameters
ParameterName:OUTSTRING
ParameterValue:adfds
ReturnStatus=0

关于SQL4306N的错误,基本上通过上面的步骤就可以解决了。如果您的问题通过上面的检查方法还没有解决,请联系IBM技术支持人员。

热心网友 时间:2022-04-09 08:12

首先单独执行一下你的存储过程是否可以运行,如果运行成功,在代码中看一下你的传入参数是否正确
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
vivo y18l 死机卡在开机界面 vivoy18l手机频繁黑屏死机怎么办? vivo y18l 死机了怎么办 vivoY18l黑屏死机解决办法 vivo y18l刷机很久都开不了机怎么? 湖北自考专升本会有学籍吗? 湖北自考专升本后可以考研吗 湖北自考申请毕业证的时间在什么时候 湖北自考专升本学历怎么查询 湖北自考专升本为什么没有学籍 在java中若要使用一个包中的类时,首先要求对该包进行导入,其关键字 四大名著分别是什么小说 JNI的误差传递大的数组java C问题,怎么解决 你心目中武侠小说的“四大名著”是什么? 鼠标一动不动 java version &quot;1.7.0_45&quot;报错 四大名著中有哪些(搞笑)穿帮镜头? rocksdb需要引入哪些jar包 rocksdbjni-5.7.3.jar 如何用java测试leveldb代码 税务注销 注销地税税务登记证要到哪里去? 怎么弄个微信分身 注销营业执照去哪里注销? 税务证注销办理 404 Not Found 四大名著有哪几本? 税务注销的流程? 办理税务注销需要提供哪些材料 具体流程是什么 公司注销税务怎么办 拼多多的黄金服饰卡怎么用 索尼75寸液晶电视机4k看有线电视会清晰吗 如何解决jni char转化为jstring乱码问题 软件包com.ice.jni.registry不存在(java编程) leveldbjni-all组件区分执行机架构吗 请问是什么 索尼4K电视剧几K的 为什么电风扇转动时会发出声音,是因为空气震动么? 电风扇转动会很响什么原因? 电脑上在哪可以看到2k或4k分辨率的电影跟电视剧? 涓什么意思?近义词和反义词是什么?英文翻译是什么? 全国商场业绩200强揭榜 你家乡哪些上榜 老旧商场如何进行业态调整 为什么转动的电风扇会比不转的轻? 热闹的商场200字_作文大全 404 Not Found 商店200字作文 上海最出名的小吃是什么? 商场每满200元减50元,妈妈买衣服实际上花了400元,原来这件衣服多少钱? 什么情况下那转动的电风扇没有风出来?