|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。Oracle收购Sun后Java前途未卜。数据|数据库|数据库毗连GettingStarted
WhataretheclassnamesoftheDriver,DataSource,ConnectionPoolDataSourceandXADataSourceimplementations?
InterfacejTDSImplementationjava.sql.Drivernet.sourceforge.jtds.jdbc.Driverjavax.sql.DataSourcenet.sourceforge.jtds.jdbcx.JtdsDataSourcejavax.sql.ConnectionPoolDataSourcenet.sourceforge.jtds.jdbcx.JtdsDataSourcejavax.sql.XADataSourcenet.sourceforge.jtds.jdbcx.JtdsDataSource^top^
WhatistheURLformatusedbyjTDS?
TheURLformatforjTDSis:- jdbc:jtds:<server_type>://<server>[:<port>][/<database>][;<property>=<value>[;...]]
复制代码 where<server_type>isoneofeithersqlserverorsybase(theirmeaningisquiteobvious),<port>istheportthedatabaseserverislisteningto(defaultis1433forSQLServerand7100forSybase)and<database>isthedatabasename--JDBCterm:catalog--(ifnotspecified,theusersdefaultdatabaseisused).ThesetofpropertiessupportedbyjTDSis:
user(required)Usernametouseforlogin.WhenusinggetConnection(Stringurl,Stringuser,Stringpassword)itsnotrequiredtosetthispropertyasitispassedasparameter,butyouwillhavetosetitwhenusinggetConnection(Stringurl,Propertiesinfo)orTdsDataSource.password(required)Passwordtouseforlogin.WhenusinggetConnection(Stringurl,Stringuser,Stringpassword)itsnotrequiredtosetthispropertyasitispassedasparameter,butyouwillhavetosetitwhenusinggetConnection(Stringurl,Propertiesinfo)orTdsDataSource.TDS(default-"8.0"forSQLServer;"5.0"forSybase)TheversionofTDStobeused.TDS(TabularDataStream)istheprotocolusedbyMicrosoftSQLServerandSybasetocommunicatewithdatabaseclients.jTDScanuseTDS4.2,5.0,7.0and8.0.Version4.2isusedbySQLServer6.5andSybase10.Version5.0isusedwithSybase11onwards.Version7.0isusedbySQLServer7.0;thisprotocolalsoworkswithSQLServer2000.Version8.0isusedbySQLServer2000andSQLServer2005.
Newerdatabaseserverversionsusuallyunderstandolderprotocolversions.ThismeansthatSQLServer7.0canbeusedwithTDS4.2,butthelimitationsoftheprotocolapplyregardlessoftheserverversion(e.g.whenusingTDS4.2VARCHARsarelimitedto255characters).Asaconclusion,youmustsetthispropertyto"4.2"whenconnectingtoSQLServer6.5orSybase.Youshouldnotsetthisvalueto"7.0"or"8.0")whenconnectingtoanyversionofSybaseastheseareSQLServerspecificprotocols.Further,youshouldnotsetthisvalueto"5.0")whenconnectingtoanyversionofSQLServerasthisisaSybasespecificprotocol.
CurrentlyjTDSautomaticallyfallsbackfrom8.0to7.0(ifusedwithSQLServer7.0)andfrom5.0to4.2(withSybase10)sospecifyingthevalueforthisparameterisonlynecessaryforSQLServer6.5.cachemetadata(default-false)WhenusedwithprepareSQL=3,settingthispropertytotruewillcausethedrivertocachecolumnmetadataforSELECTstatements.Cachingthemetadatawillreducetheprocessingoverheadwhenreusingstatementsthatreturnsmallresultsetsthathavemanycolumnsbutmayleadtounexpectederrorsifthedatabaseschemachangesafterthestatementhasbeenprepared.Usewithcare.OnlyapplicabletoSQLServer(thereisnoprepareSQL=3modeforSybase).charset(default-thecharactersettheserverwasinstalledwith)Veryimportantsetting,determinesthebytevaluetocharactermappingforCHAR/VARCHAR/TEXTvalues.Appliesforcharactersfromtheextendedset(codes128-255).ForNCHAR/NVARCHAR/NTEXTvaluesdoesnthaveanyeffectsincethesearestoredusingUnicode.domainSpecifiestheWindowsdomaintoauthenticatein.Ifpresentandtheusernameandpasswordareprovided,jTDSusesWindows(NTLM)authenticationinsteadoftheusualSQLServerauthentication(i.e.theuserandpasswordprovidedarethedomainuserandpassword).Thisallowsnon-WindowsclientstologintoserverswhichareonlyconfiguredtoacceptWindoesauthentication.
Ifthedomainparameterispresentbutnousernameandpasswordareprovided,jTDSusesitsnativeSingle-Sign-OnlibraryandlogsinwiththeloggedWindowsuserscredentials(forthistoworkonewouldobviouslyneedtobeonWindows,loggedintoadomain,andalsohavetheSSOlibraryinstalled--consultREADME.SSOinthedistributiononhowtodothis).instanceNamedinstancetoconnectto.SQLServercanrunmultipleso-called"namedinstances"(i.e.differentserverinstances,runningondifferentTCPports)onthesamemachine.WhenusingMicrosofttools,selectingoneoftheseinstancesismadebyusing"<host_name><instance_name>"insteadoftheusual"<host_name>".WithjTDSyouwillhavetosplitthetwoandusetheinstancenameasaproperty.appName(default-"jTDS")Applicationname.Nopracticaluse,itsdisplayedbyEnterpriseManagerorProfilerassociatedwiththeconnection.progName(default-"jTDS")Clientlibraryname.Nopracticaluse,itsdisplayedbyEnterpriseManagerorProfilerassociatedwiththeconnection.wsid(default-theclienthostname)WorkstationID.Nopracticaluse,itsdisplayedbyEnterpriseManagerorProfilerassociatedwiththeconnection.macAddress(default-"000000000000")NetworkinterfacecardMACaddress.ItsdisplayedbyEnterpriseManagerorProfilerassociatedwiththeconnectionandisneededtoresolvesomeissuesregardingthenumberofclientsallowedbytheSQLServerlicense.TheMACaddresscannotbedeterminedautomaticallyfromJava(i.e.withoutusingnativecode)soyoullhavetospecifyityourselfifyouneedit.sendStringParametersAsUnicode(default-true)DetermineswhetherstringparametersaresenttotheSQLServerdatabaseinUnicodeorinthedefaultcharacterencodingofthedatabase.ThisseriouslyaffectsSQLServer2000performancesinceitdoesnotautomaticallycastthetypes(as7.0does),meaningthatifaindexcolumnisUnicodeandthestringissubmittedusingthedefaultcharacterencoding(ortheotherwayaround)SQLServerwillperformanindexscaninsteadofanindexseek.lastUpdateCount(default-true)IftrueonlythelastupdatecountwillbereturnedbyexecuteUpdate().Thisisusefulincaseyouareupdatingorinsertingintotablesthathavetriggers(suchasreplicatedtables);theresnowaytomakethedifferencebetweenanupdatecountreturnedbyatriggerandtheactualupdatecountbuttheactualupdatecountisalwaysthelastasthetriggersexecutefirst.Iffalseallupdatecountsarereturned;usegetMoreResults()toloopthroughthem.prepareSQL(default-3forSQLServer,1forSybase)ThisparameterspecifiesthemechanismusedforPreparedStatements.ValueDescription0SQLissenttotheservereachtimewithoutanypreparation,literalsareinsertedintheSQL(slower)1TemporarystoredproceduresarecreatedforeachuniqueSQLstatementandparametercombination(faster)2sp_executesqlisused(fast)3sp_prepareandsp_cursorprepareareusedinconjunctionwithsp_executeandsp_cursorexecute(faster,SQLServeronly)packetSize(default-4096forTDS7.0/8.0;512forTDS4.2/5.0)Thenetworkpacketsize(amultipleof512).tcpNoDelay(default-true)truetoenableTCP_NODELAYonthesocket;falsetodisableit.lobBuffer(default-32768)TheamountofLOBdatatobufferinmemorybeforecachingtodisk.ThevalueisinbytesforBlobdataandcharsforClobdata.maxStatements(default-500)Thenumberofstatementprepareseachconnectionshouldcache.Avalueof0willdisablestatementcaching.AvalueofInteger.MAX_VALUE(2147483647)willenablefastcaching(useslessmemoryandhasnooverheadassociatedwithremovingstatements);thecachewillneverreleaseanycachedstatements,soalthoughexperiencehasshownthatthisisusuallynotaproblemwithmostapplications,usewithcare.loginTimeout(default-0)Theamountoftimetowait(inseconds)forasuccessfulconnectionbeforetimingout.namedPipe(default-false)Whensettotrue,namedpipecommunicationisusedtoconnecttothedatabaseinsteadofTCP/IPsockets.Whentheservernameis"localhost"orstartswith"127.",localnamedpipes(viatheWindowsfilesystem)areused.TheseusuallyhavebetterperformancethanTCP/IPcommunication,butonlyworkwhentheSQLServerandclientareonthesamemachine.Iftheservernameisnot"localhost"or"127.something"theJCIFSlibraryisused.JCIFSisanamedpipeoverTCP/IPimplementationandrequiresWindows(NTLM)authentication,sothedomainparameterisrequired.
Thisfeaturesupportstheinstanceparameter(whichchangesthenamedpipeURL),butitdoesnotcurrentlysupportthenamedpipeatalocationotherthan/sql/queryontheserver.Theportparameterisignoredifset.xaEmulation(default-true)Whensettotrue,emulateXAdistributedtransactionsupport,whensettofalseuseexperimentaltruedistributedtransactionsupport.TruedistributedtransactionsupportisonlyavailableforSQLServer2000andrequirestheinstallationofanexternalstoredprocedureinthetargetserver(seetheREADME.XAfileinthedistributionfordetails).ssl(default-off)SpecifiesifandhowtouseSSLforsecurecommunication.ValueDescriptionoffSSLisnotrequestorused;thisisthedefaultrequestSSLisrequested;iftheserverdoesnotsupportitthenaplainconnectionisusedrequireSSLisrequested;iftheserverdoesnotsupportitthenanexceptionisthrownauthenticateSameasrequireexcepttheserverscertificatemustbesignedbyatrustedCAbatchSize(default-0forSQLServer;1000forSybase)Controlshowmanystatementsaresenttotheserverinabatch.Theactualbatchisbrokenupintopiecesthislargethataresentseparately.ThereasonforthisistoavoidSybase"hangs"causedbyrunningoutofspacewithverylargebatches.TheproblemdoesntseemtooccurwithSQLServer,hencethedefaultlimitof0(unlimited)inthiscase.useCursors(default-false)InstructsjTDStouseserversidecursorsinsteadofdirectselects(AKAfirehosecursors)forforward-onlyread-onlyresultsets(withothertypesofresultsetsserver-orclient-sidecursorsarealwaysused).
WithfirehosecursorstheSELECTqueryissentandtheserverrespondswithalltheresultingrows.Thisisthefastestapproachbutitmeansthatthedriverhastocacheallresultsifanotherrequestneedstobemadebeforeallrowshavebeenprocessed.SowhenusingmultipleStatementsperConnectionitispreferabletohaveserver-sidecursorsinstead;thesewillallowthedrivertorequestonlyalimitednumberofrowsatatime(controllablethroughthefetchSizepropertyofaStatement).Thismeansextrarequest-responsecycles,butlesscachingbythedriver.
WithSQLServerasocalledfastforward-onlycursorwillbecreatedwhenthispropertyissettotrue.WithSybaseausualforward-onlyread-onlycursoriscreated.bufferMaxMemory(default-1024)Controlstheglobalbuffermemorylimitforallconnections(inkilobytes).Whentheamountofbufferedserverresponsepacketsreachesthislimitadditionalpacketsarebufferedtodisk;thereishoweveroneexception:eachStatementgetstobufferatleast<bufferMinPackets>tomemorybeforethislimitisenforced.Thismeansthatthislimitcanandwillusuallybeexceeded.
ServerresponsesarebufferedtodiskonlywhenarequestismadeonaStatementwhileanotherStatementbelongingtothesameConnectionstillhasntprocessedallitsresults.ThesesituationscanbeavoidedinmostcasesbysettingtheuseCursorsproperty,butthiswillalsoaffectperformance.
SeealsobufferMinPackets.bufferMinPackets(default-8)Controlstheminimumnumberofpacketsperstatementtobuffertomemory.EachStatementwillbufferatleastthismanypacketsbeforebeingforcedtouseatemporaryfileifthe<bufferMaxMemory>isreached,toensuregoodperformanceevenwhenoneStatementcachesaverylargeamountofdata.
ServerresponsesarebufferedtodiskonlywhenarequestismadeonaStatementwhileanotherStatementbelongingtothesameConnectionstillhasntprocessedallitsresults.ThesesituationscanbeavoidedinmostcasesbysettingtheuseCursorsproperty,butthiswillalsoaffectperformance.
SeealsobufferMaxMemory.useLOBs(default-true)Controlswhetherlargetypes(IMAGEandTEXT/NTEXT)shouldbemappedbydefault(whenusinggetObject())toLOBsorJavatypes(Stringandbyte[]).ThedefaultJDBCtypeconstantreturnedisalsocontrolledbythisproperty:Types.BLOBforIMAGEandTypes.CLOBforTEXT/NTEXTwhentrue,Types.LONGVARBINARYforIMAGEandTypes.LONGVARCHARforTEXT/NTEXTwhenfalse.
ThisisusefulwhenprintingoutdirectlythevaluesreturnedbygetObject()(e.g.whenusingJSTLorotherframeworks),asBlobandClobdontimplementtoString()(bothbecauseitsnotrequiredandbecauseitcaneasilyleadtoOutOfMemoryErrorsinunexpectedsituations,suchaswhenloggingdata).ThedefaultsettingoftruehastheadvantagethattheamountofdatathatiscachedinmemoryforalargeobjectcanbecontrolledviathelobBufferproperty;asettingoffalsewillstillusetheBlobandClobimplementationsinternallybutthevalueswillbematerializedtomemorywhengetObject()iscalled,possiblyleadingtomemoryissues.PropertiescanbepassedtojTDSinoneofthreeways:intheURL,inthePropertiesobjectpassedtogetConnection()orbyusingtheTdsDataSourcessetters(ifconnectionsareobtainedthroughaDataSourceratherthanusingtheDriverManager).BecausethereisnoURLwhenusingtheTdsDataSourcetherearethreeotherproperties(withsettersandgetters)totaketheplaceofthoseitemsthatarepartoftheURLssyntax:serverName,portNumberanddatabaseName(theirmeaningshouldbequiteclear).
^top^
jTDSissupposedtobethefastestJDBCdriveraround.Haveyougotanyfigurestoprovethat?Orevenbetter,abenchmarkIcanrunmyself?
Actuallywedohavebenchmarkresultsfromtwodifferentbenchmarks,bothdevelopedbylargecommercialSQLServerJDBCdrivervendorstodemonstratetheperformanceoftheirowndrivers.Inouroppinionthisisbetterthanhavingabenchmarkofourown,whichcouldbedesignedinsuchawayastogivejTDStheedge.Thesebenchmarksarefreetodownloadsoweencourageyoutodoitandrunthemyourself.
WehavebenchmarkedjTDSagainstthetwomostusedcommercialdriversandofcoursetheMicrosoftdriverandtheJDBC-ODBCbridge,usingthesebenchmarks:i-netsoftwaresBenchTest2.1forMSSQLServerandJNetDirectsJDBCPerformanceBenchmark.Herearetheresultsofthei-nettest:BenchTest2.1forMSSQLServer.TheJNetDirectlicenseprecludespublicationofperformancetestresults.However,youcanrunanyofthebenchmarksyourself,theeffortisminimal.
^top^
WhichJDBCfeaturesareandwhichfeaturesarenotsupportedbyjTDS?
jTDSoffersfullsupportforallJDBC3.0features:forward-onlyandscrollable/updateableresultsets,batchupdates,preparedandcallablestatements,unlimitednumberofstatementsperconnection,completedatabaseandresultsetmetadata,andaDataSourceimplementation(whichalsoimplementsConnectionPoolDataSourceandXADataSource).Featuressuchasgeneratedkeysretrieval,namedstoredprocedureparameters,andsavepointsarealsoimplemented.
TheonlymajorfeaturesmissingfromjTDSareconnectionpoolingandrowsets;thereasonforleavingtheseoutisthattherearefreeimplementationsavailable,probablymuchbetterthananythingwecouldcomeupwith.CheckoutthejTDSfeaturematrixformoredetails.
^top^
CanjTDSbeusedinamultithreadedapplication?
Asageneralprinciplewetryandkeepsynchronizationtoaminimumbothforperformanceanddeadlockreasons.TheonlypartofjTDSweguaranteeisthreadsafeistheConnectionobject,andmultithreadedaccesstoStatementsisdiscouraged(exceptforissuingcancels).
Asaconclusiontheonlysafemultithreadingscenariosarethese:(i)oneConnectionwithmultipleStatements,eachStatementusedbyasinglethreadand(ii)aStatementusedbyonethreadandcancelledbysomeotherthread.Scenario(i),whileitdoeswork,isnotnecessarilyagoodsolutionbecauseitrequiresalotoflockingandwaitingonthesamenetworkconnectionplus(lastbutnotleast)alotofcaching.
^top^
ErrorConditions
WhydoIgetaClassNotFoundErrorwhencallingClass.forName("net.sourceforge.jtds.jdbc.Driver")?
ClassNotFoundErroristhrownbytheclassloaderwhenitcannotfindacertainclass.Inthiscaseitsthenet.sourceforge.jtds.jdbc.Driverclass,whichmeansthatjtds.jarisnotintheclasspath.Ifyouaregettingthisinanapplication,startyourapplicationwith- java-cp<path_to_jtds>/jtds.jar<main_class>
复制代码 Ifyouexperiencethisprobleminaservlet/JSPyouwillhavetoaddjtds.jartoyourwebapplicationsclasspath(e.g.byeditingtheapplicationsweb.xmlfileorbycopyingthejarintotheapplications/servers/libdirectory).
Note:ThenameofthejTDSjarfilemaybejtds-1.1.jarorsomethingsimilar.Ifthatsthecase,replacejtds.jarintheaboveexamplewithjtds-1.1.jarorwhateveryourspecificfilenameis.
^top^
WhydoIgetajava.sql.SQLException:"Nosuitabledriver"whentryingtogetaconnection?
The"Nosuitabledriver"exceptionisthrownbytheDriverManagerwhennoneoftheregisteredDriverimplementationsrecognizesthesuppliedURL.ThismeansthatyoueitherdidnotregisterjTDSwiththeDriverManagerfirst(bycallingClass.forName("net.sourceforge.jtds.jdbc.Driver"))oryoumistypedtheURL(e.g."jbdc:jtds:..."insteadof"jdbc:jtds:...").
Acommonmistakeistoappendasemicolon(";")totheendoftheURL(e.g."jdbc:jtds:sqlserver://server/db;TDS=7.0;"iswrong!).
FormoreinformationaboutURLformatandthepropertiesthatmaybepassedtojTDShavealookatthejTDSURLformat.
^top^
WhydoIgetjava.sql.SQLException:"NetworkerrorIOException:Connectionrefused:connect"whentryingtogetaconnection?
The"Connectionrefused"exceptionisthrownbyjTDSwhenitisunabletoconnecttotheserver.Theremaybeanumberofreasonswhythiscouldhappen:
- Theservernameismisspelledortheportnumberisincorrect.
- SQLServerisnotconfiguredtouseTCP/IP.EitherenableTCP/IPfromSQLServersNetworkUtilityapporhavejTDSconnectvianamedpipes(seetheURLformatforinformationonhowtodothis).
- Thereisafirewallblockingport1433ontheserver.
TocheckwhetherTCP/IPisenabledandtheportisnotblockedyoucanuse"telnet<server_host>1433".Untiltelnetdoesntconnect,jTDSwonteither.Ifyoucantfigureoutwhy,askyournetworkadministratorforhelp.
^top^
Wheredoesoneplaceaninstancenameintheconnectstring?Connectingwith"jdbc:jtds:sqlserver://hostinstance:port/database"givesanSQLExceptionwiththemessage"Logonfailed".
Youwillhavetousetheinstanceproperty(eitherappendittotheURLorplaceitintothePropertiesyousupplytogetConnection)insteadofdoingittheMicrosoftway.Sorry,butjTDS(anditsancestorFreeTDS)existedalongtimebeforenamedinstancessotheURLcouldnotbechanged(andusingitthiswayconfusestheURLparser).
^top^
WhydoIgetajava.sql.SQLException:"UnabletogetinformationfromSQLServer"whentryingtoconnecttoanSQLServerinstance?
Theexceptionyouaregettingisusuallycausedbyatimeout.WhenconnectingtonamedinstancesjTDSneedstoconnectviaUDPtoport1434togetinformationaboutavailableSQLServerinstances.Whiledoingthisittimesout,throwingtheexceptionyousee(whichmeansthatjTDSwasnotabletogetinformationabouttherunninginstances).
Connectiontimeoutsoccurwhenthereisnoserverlisteningontheport(BTW,areyousureyourSQLServerisconfiguredtouseTCP/IPandthatyouactuallyusenamedinstances?).
OnSQLServer2005theSQLBrowserservicemustberunningontheserverhostastheinstancenamelookupportUDP1434ishostedbythisserviceonSQLServer2005ratherthantheSQLServeritself.ThedefaultinstalldoesnotconfiguretheSQLBrowserservicetostartautomaticallysoyoumustdoitmanually.
^top^
Iwashopingthatappending";domain=X"totheURLwouldbeenoughonaworkstationthatwasalreadyloggedintodomainX.WhydoIstillneedtoprovideausernameandpassword?
jTDSisatype4(pureJava)JDBCdriver.Thismeans(amongotherthings)thatitcannotaccessplatform-specificfeatures,suchasdeterminingthecurrentlyloggeduserandhiscredentials.jTDSisdistributedwithanativelibrary(DLL)forSingle-Sign-Onsupport,butthatonlyworksonWindows(pleaseconsultREADME.SSOinthedistributionpackageforinformationonhowtoinstallit).
WithoutthenativeSSOlibraryinstalledyoustillhavetoprovidetheusernameandpasswordbecauseotherwisejTDScannotdetermineusercredentials.Thereisagoodsidetothis:usersonnon-WindowsplatformsareabletologinusingWindowscredentialsbyprovidingthemintheURL,alongwiththedomainname.
^top^
executeQuery()throwsjava.sql.SQLException:"TheexecuteQuerymethodmustreturnaresultset.".
TheJDBCspecandAPIdocumentationforStatementbothstatethatexecuteQuery()isintendedtobeusedwithqueriesthatreturnaResultSet,typicallySELECTstatements.Onthetheotherhand,executeUpdate()isintendedforINSERT,UPDATE,DELETEorDDLstatementsthatreturnupdatecounts.Bothofthese(ResultSetsandupdatecounts)areconsideredbyJDBCtobe"results".ForqueriesthatreturnmultipleresultstheJDBCspecrequiresexecute()tobeused.
Ifyoulllookatthequeryyouaretryingtoexecute,youllseethatitprobablyreturnsanupdatecountfirst,followedbyaResultSet.SoaccordingtotheJDBCspecyoushoulduseexecute()torunit,callgetMoreResults()toskiptheupdatecountandthencallgetResultSet()toobtaintheResultSetyouwant.
Asasidenote,TheMicrosoftdriver(andprobablytheothers,too)"optimize"thisbehaviorbyskippingovertheupdatecount,whichiswrongaccordingtotheJDBCspec.So,formaximumcompatibility,itisrecommendedthatyouuseexecute()anytimeyourunqueriesreturningmorethanoneresulteveniftheparticulardriveryouareusingallowsyoutodootherwise.
ThesamethinghappenswiththeODBCSQLdriverandotherconnectors.Acommonsolutionratherthantheinelegantexecute()andthencyclingthroughmultipleresultsets,istosupresstheupdatecountsforstatementsyouareuninterestedin.Thisiscommonifsayyouarequeryingastoredprocedurethatcreatesatemptable,runsupdatesagainstitandthenreturnsthetableasaresultset.Youcansuppressalltheextra"queryresults"byspecifying"SETNOCOUNTON".
^top^
Igetjava.sql.SQLException:"ResultSetmayonlybeaccessedinaforwarddirection"or"ResultSetisreadonly"whenusingascrollable/updateableResultSet.
Therearethreepossiblecausestothis(ifweexcludenotcreatingtheResultSetwiththeappropriatetypeandconcurrencyinthefirstplace):
- TheexecutedquerymustbeasingleSELECTstatementoracalltoaprocedurethatconsistsofasingleSELECTstatement(evenaSETorPRINTwillcausetheresultingResultSettobeforwardonlyreadonly).ThisisaSQLServerlimitationandtheresnotmuchjTDScandoaboutit.
- Thescrollinsensitive/updateablecombinationisnotsupportedbySQLServer,sosuchaResultSetisautomaticallydowngradedtoscrollinsensitive/read-onlybytheserver.Usethescrollsensitive/updateablecombinationanditshouldwork.
- Theotherpossiblecauseisthatthecursoriskeyset-basedandeitherthetableyouareselectingfromdoesnothaveauniqueprimarykeyorthatprimarykeyisnotincludedinyourSELECT.SeetheSQLServerDocumentationoncursortypesformoreinformation.
InbothcasesifyoucallStatement.getWarnings()rightaftercallingexecuteQuery()youllgetawarningabouttheResultSetbeingdowngraded.Also,pleasetakealookatourResultSetsupportpageforsomeadditionalinformationandtips.
^top^
NotallSQLExceptionsthrownbyjTDSseemtohaveassociatedmeaningfulSQLstatevalues.
Indeed,someSQLExceptionsarereportedwithacorrectstatecodeandsomenot.AstheserveritselfdoesnotreturnanSQLstatecode,theSQLMessageclassassociatesnativeerrornumberswithSQLstatecodes(actuallytheresaverycomprehensivemapthere);SQLServeroriginatederrorsandwarningsthatarenotfoundinthismaparegivenadefaultcodeofS1000,respectively01000.ThisiswhathappenswithSQLServer-returnederrorsandwarningsandisconsistentwithhowotherdrivershandleexceptions.Wehavedoneourbesttomapasmanyerrorsandwarnings,howeverifyoufindsomecaseinwhichotherJDBCorODBCdriversreturnspecificSQLstatesandjTDSdoesntorjTDSreturnedSQLstatesthatareobviouslywrong,pleaseletusknow.Wewillmakethenecessarychanges.
SeetheSQL92specforthecompletelistanddescriptionofSQLstatecodes.
^top^
BatchprocessingusingexecuteBatch()hangsorisunreliableonSybase.
WhenexecutinglargebatchesonSybasetheclientapplicationmayhangortheresponsetimemayvaryconsiderably.Theclientmaybesuspendedifthesystemlogfillssocheckthatthelogspaceissufficientforthebatchyouaretryingtoload.YoucancontroltherealbatchsizeusingthebatchSizeparameter;settingittoanon-zerovaluewillbreakupbatchesintosmallerpiecesonexecution,hopefullyavoidingtheproblem.
Itisalsorecommendedthatyouexecuteeachbatchinatransaction(i.e.withautocommitsettofalse).
^top^
IncorrectBehavior
CallableStatementoutputparametergetterthrowsjava.sql.SQLException:"ParameterXhasnotbeenset.".
Whenexecutingastoredprocedure(oranyquery,forthatmatter)theresponsefromtheSQLServerisserializedinthesameorderitisexecutedin:forstoredproceduresthismeansResultSetsandupdatecountsfirst,outputparametersandreturnvaluelast.jTDSonlycachesupdatecounts,notResultSetsbecausetheycouldeasilycauseOutOfMemoryErrorsoraddimportantperformanceoverheadsifcachedtodisk(theresponsewouldhavetobeparsedtwice,forexample).
Asaconclusion,whenexecutingstoredproceduresthatonlyreturnupdatecountsoutputparameterswillbeavailableimmediately,asjTDSwillprocessandcachethewholeresponse.ButifthestoredprocedurereturnsatleastoneResultSetjTDSwillonlycachetheupdatecountsuptothefirstResultSetandyouwillhavetocallgetMoreResults()toprocessalltheresults.SoforproceduresreturningResultSetsyouwillhavetoloop,consumingallresultsbeforereadingtheoutputparameters(i.e.untilgetMoreResults()returnsfalseANDgetUpdateCount()returns-1).
Incaseyouarewonderingifthisisright,thisisaquotefromtheCallableStatementAPIdocumentation:"Formaximumportability,acallsResultSetobjectsandupdatecountsshouldbeprocessedpriortogettingthevaluesofoutputparameters".Althoughthismeansthata"good"drivercould"fix"thisbehavior,fixingitwouldimplycachingthewholeserverresponse,equalingahugeperformancedrop.
Theexceptionisthrownbecauseitsbettertowarntheuserthattheoutputparametersarenotyetsetinsteadofleavingtheimpressionthatallisokandcauseother,hardertodetectproblems.
^top^
PreparedStatement.executeUpdate()returnsanincorrectupdatecount.
Thisiscausedbytriggers;replicationisalsoimplementedthroughtriggers,soyouwillencounterthisissueonreplicateddatabasestoo.TherootcauseisthattriggersalsoreturnupdatecountsandjTDScantmakethedifferencebetweentheseupdatecountsandthe"real"one(neithercouldanyotherSQLServerclient).However,theupdatecountyouneedisthelastofthem(becausetheactualUPDATE/INSERT/DELETEgetsexecutedonlyafterthetriggers)andthereisluckilyaparameteryoucanspecifyintheURL(ortheconnectionPropertiesorintheDataSource)inorderforjTDStoreturnonlythislastupdatecount(andignoretherestofthem).ThisparameterislastUpdateCountandyoucanfindoutmoreaboutithere.
PleasenotethatsettinglastUpdateCounttotruecouldcauseproblemsifyouusequeriesthatdoactuallyreturnmorethanoneupdatecount(suchasqueriesconsistingofmultipleupdates/inserts),becauseitwillalsoreturnonlythelastoftheseupdatecounts.Althoughqueriesreturningmultipleresultsarenotverycommon,itisthereasonwhythisbehavioriscustomizablefromtheURL.PleasenotethatthisflagonlyaltersthebehaviorofexecuteUpdate();execute()willstillreturnallupdatecounts.
IfyouhavebothqueriesconsistingofmultipleUPDATEs/INSERTs/DELETEsandtriggersyouwontbeabletosetlastUpdateCounttotrueifyouwantalltheupdatecounts,soyouwillhavetoskipovertheirrelevantupdatecountsbycallinggetMoreResults()yourself,whenneeded.
^top^
MemoryUsage
MemoryusagekeepsincreasingwhenusinggeneratedPreparedStatements.
Normally,withaJDBCdriver,PreparedStatementsareprecompiledoncreation,whichgivesincreasedperformanceiftheyareusedasufficientnumberoftimes.jTDStakesthisonestepfurther:whenyoucreateaPreparedStatement,jTDScachesitinternallyandkeepsitthereevenafteryoucloseitsothateverytimeyoucreateitagainitdoesntneedtoberecompiled,itsjustfetchedfromthecache.ThisgivesjTDSa2xperformanceincreaseoverthenextfastestdriverinsome(notsouncommon)cases.Forexample,ifyouhaveamethodthatinsertsarowintoatablebycreatingaPreparedStatement,usingitonceandthenclosingit,yourstatementwillbecompiledonlyonceforeachConnection,nomatterhowmanytimesyoucallthatmethod.
ThenumberofstatementsthatarekeptopensimultaneouslycanbecontrolledwiththemaxStatementsparameter;seethejTDSURLformatformoreinformation.
FutureversionsofjTDSwillallowthetypeofcache(LRU,FIFO,etc)tobeselected.
^top^
TDSProtocolVersion
ImtryingtoconnecttoSQLServer6.5,butithangswhencallinggetConnection().
jTDSusesbydefaultTDS8.0(whichisSQLServer2000sprotocol)tocommunicatewiththedatabaseserver.WhenjTDSsendsthe8.0loginrequestSQLServer6.5doesntunderstanditsoitreturnsa4.2error(Loginfailed).ButbecausejTDSisexpectingaTDS8.0packetasaresponse(notaTDS4.2packet)itdoesntproperlyunderstandtheresponsepacketandithangswaitingformoredatafromtheserver.Thesolutionistosetthe"TDS"propertyto"4.2"(throughtheURLorPropertiesobjectpassedtogetConnection()orusingtheappropriatesetterofTdsDataSource,ifyouareusingtheTdsDataSource).
FormoreinformationaboutURLformatandthepropertiesthatmaybepassedtojTDShavealookatthejTDSURLformat.
^top^
Whydocolumnnamesmorethan30characterslong,getchoppedoffat30characters?
YouareveryprobablyusingTDS4.2tocommunicatewiththeSQLServer.TDS4.2istheprotocolusedbySQLServer6.5andithasthelimitationsofSQLServer6.5(amongwhichamaximumcolumnnamesizeof30characters).jTDS0.2andearlieruseTDS4.2bydefault.InordertochangethatyouhavetospecifyitexplicitlyinthePropertiesortheURLyousupplywhenyoucreatetheconnection.Ifyouexperiencethisproblemwithversions0.3orlater,thenyouhavespecified(intheconnectionpropertiesorURL)thatTDS4.2shouldbeused;removethatsetting.
FormoreinformationaboutURLformatandthepropertiesthatmaybepassedtojTDShavealookatthejTDSURLformat.
^top^
jTDSfetchesonlythefirst4KbofIMAGEdata.
YouareveryprobablyusingTDS4.2tocommunicatewiththeSQLServer.TDS4.2istheprotocolusedbySQLServer6.5andithasthelimitationsofSQLServer6.5(amongwhichamaximumsizeforIMAGEdataof4Kb).jTDS0.2andearlieruseTDS4.2bydefault.InordertochangethatyouhavetospecifyitexplicitlyinthePropertiesortheURLyousupplywhenyoucreatetheconnection.Ifyouexperiencethisproblemwithversions0.3orlater,thenyouhavespecified(intheconnectionpropertiesorURL)thatTDS4.2shouldbeused;removethatsetting.
FormoreinformationaboutURLformatandthepropertiesthatmaybepassedtojTDShavealookatthejTDSURLformat.
^top^
Technicalsupport
IsthereanycommercialtechnicalsupportavailableforjTDS?
ForthemomentyoucangetofficialtechnicalsupportfromindividualdevelopersofjTDS;contactanyofusandwellbehappytoprovideyouwithourtechsupporttermsandconditions.Ofcourse,wewillkeepofferingsupportonourSourceForgeforumsjustaswediduntilnow;weareonlytryingtoencourageadoptionofjTDS,notmakeafortuneoutofit.
Asforwherethetechnicalsupportmoneywillgo,partofthemwillberetainedbythedeveloperandpartofthemwillgobackintojTDS.CurrentlytheaimistoraiseUS$2000,topayforJDBCcertification.Were100%surejTDSwillpassthecertificationtestsuite,wejustneedthemoneyforit.Tothisend,wealsoacceptdonations.
^top^
Other
IdidntfindtheanswertomyprobleminthisFAQ.WhatshouldIdo?
IfyouneedhelpwithanyotherjTDS-relatedissue,searchtheHelpforumfirstandifyoustilldontfindanything,postaquestion.Itwillusuallygetansweredwithin24hours.Onething,though:pleaseregisterasaSourceForgememberandloginifyouhaventdonesoyet,soyoucanbeautomaticallynotifiedofupdatestothequestionsyoupost.
Ifyouencounteredanissuethatyouhavetestedandretestedandyouresureitsabug,usetheBugslinkontopofthepage.Again,makesureyouareaSourceForgememberANDthatyouareloggedinwhenyoupost.
Java到底会发战成什么样,让我们拭目以待吧,我始终坚信着java会更好。以上都是俺个人看法,欢迎大家一起交流. |
|