15. august 2003 - 11:56
Der er
11 kommentarer og 1 løsning
CallableStatement mod MS SQL Server 2000
Hej, Jeg har installeret en MS SQL Server 2000 lokalt på min maskine og har oprettet tabeller og stored procedures. Men har følgende problem med denne kode: public ResultSet testStoredProcedure() { CallableStatement cs = null; ResultSet rs = null; String command = "{?=call dbo.CustOrderHist (?) }"; try { cs = con.prepareCall( command ); cs.setString( 1, "ANTON" ); cs.registerOutParameter( 2, Types.VARCHAR ); cs.registerOutParameter( 3, Types.VARCHAR ); rs= cs.executeQuery(); } catch ( SQLException e ) { e.printStackTrace(); //To change body of catch statement use Options | File Templates. } return rs; } Jeg får en exception: java.lang.ArrayIndexOutOfBoundsException at com.microsoft.jdbc.base.BaseParameters.set(Unknown Source) at com.microsoft.jdbc.base.BaseCallableStatement.registerOutParameter(Unknown Source) at SQLParserTest.testStoredProcedure(SQLParserTest.java:127) at SQLParserTest.main(SQLParserTest.java:108) Exception in thread "main" Process terminated with exit code 1 Proceduren returnerer to rækker og tager en streng som input. Hvorfor denne exception?
Annonceindlæg tema
Forsvar & beredskab
Cybersikkerhed, realtidsdata og robuste it-systemer er blevet fundamentet for moderne forsvar.
15. august 2003 - 12:01
#1
Du angiver en SQL sætning med 1 argument: String command = "{?=call dbo.CustOrderHist (?) }"; og så sætter du typen for parameter 2 og 3. Det skal gå galt !
15. august 2003 - 12:02
#2
En out parameter er et argument til SP som returnerer en værdi. Et result set som returneres fra en SP er noget helt andet.
15. august 2003 - 12:03
#3
Så mit gæt er at du skal droppe de 2 registerOutParameter og bare fiske data ud fra ResultSet.
15. august 2003 - 12:07
#4
Hvis jeg ændrer det til: public ResultSet testStoredProcedure() { CallableStatement cs = null; ResultSet rs = null; String command = "{call dbo.CustOrderHist (?) }"; try { cs = con.prepareCall( command ); cs.setString( 1, "ANTON" ); // cs.registerOutParameter( 2, Types.VARCHAR ); // cs.registerOutParameter( 3, Types.VARCHAR ); rs= cs.executeQuery(); } catch ( SQLException e ) { e.printStackTrace(); //To change body of catch statement use Options | File Templates. } return rs; } Virker det. Læg mærke til, at ? foran =call er væk, men burde ? ikke være med, nu når proceduren returnerer noget?
15. august 2003 - 12:10
#5
? = er SP'ens return value. En SP kan både: - have out parametre - returnere en værdi - producere result sets Den ? = skal du nok have defineret en type for med cs.registerOutParameter på index 0. [ikke helt sikker - det er lang tid siden jeg har leget med SP fra Java]
15. august 2003 - 12:26
#7
Hvis du skal hente retur værdien skal skal der ? = på. Men det er muligt at typen af retur værdien ikke skal registereres men at du bare kan get'e den efter execute.
15. august 2003 - 12:27
#8
Hvis du skal have mere en en værdi tilbage skal du vel returnere et resultset !? (det er da også det din test metode gør)
15. august 2003 - 12:38
#9
Ja, min testmetode gør det, men det var blot for at lege med det. Der findes en metode, der hedder getString( int i ), som man kan kalde på sit CallableStatement, og derved trække info. ud af det. Det skal bruges til, at brugeren får præsenteres response som et XML doc, der skal have en bestemt syntaks.
15. august 2003 - 12:43
#10
Ja. Men getString(3) henter det tredie output argument og getString(0) henter en string retur værdi. Men så vidt jeg ved kan man ikke returnere flere rækker på den måde. For at gøre det skal du returnere et eller flere ResultSet.
15. august 2003 - 21:46
#11
Jeg prøvede lige at lave et lille eksempel. Spørgsmåls tegnene nummereres fra 1 af uanset om det først er result. Desværre Sybase fordi SQLServer og NT Security var ikke lige i humør til at lege med JDBC idag. Men det er stort set det samme. Stored procedure: CREATE PROCEDURE TEST_MULTIOUT @inarg INTEGER, @outarg INTEGER OUTPUT AS SELECT @outarg = 123 SELECT * FROM T1 SELECT * FROM T1 RETURN -@inarg så vi har et in argument og et out argument, vi returnerer en result værdi og vi returnerer 2 result sets. Så der er lidt af det hele ! import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Types; public class UseSP { public static void main(String[] args) throws Exception { Class.forName("com.sybase.jdbc2.jdbc.SybDriver"); Connection con = DriverManager.getConnection("jdbc:sybase:Tds:arnepc2:5000", "sa", ""); con.setCatalog("Test"); CallableStatement cstmt = con.prepareCall("{? = CALL TEST_MULTIOUT(?,?)}"); cstmt.registerOutParameter(1, Types.INTEGER); cstmt.setInt(2, 5); cstmt.registerOutParameter(3, Types.INTEGER); cstmt.execute(); while(cstmt.getMoreResults()) { ResultSet rs = cstmt.getResultSet(); while(rs.next()) { System.out.println(rs.getInt(1) + " " + rs.getString(2)); } } System.out.println("return value = " + cstmt.getInt(1)); System.out.println("out parameter = " + cstmt.getInt(3)); cstmt.close(); con.close(); } } output: 1 A 2 BB 3 CCC 1 A 2 BB 3 CCC return value = -5 out parameter = 123 og så er det bare at vælge hvad du har brug for !
19. august 2003 - 18:03
#12
Glimrende! Lige det der fik de sidste brikker til at falde på plads!
Kurser inden for grundlæggende programmering