|
1 | 1 | <!--
|
2 |
| -$Header: /cvsroot/pgsql/doc/src/sgml/Attic/jdbc.sgml,v 1.45 2003/06/30 16:39:42 barry Exp $ |
| 2 | +$Header: /cvsroot/pgsql/doc/src/sgml/Attic/jdbc.sgml,v 1.46 2003/08/06 23:50:19 barry Exp $ |
3 | 3 | -->
|
4 | 4 |
|
5 | 5 | <chapter id="jdbc">
|
@@ -323,8 +323,9 @@ db.close();
|
323 | 323 | a <classname>Statement</classname> or
|
324 | 324 | <classname>PreparedStatement</classname>, you can use issue a
|
325 | 325 | query. This will return a <classname>ResultSet</classname>
|
326 |
| - instance, which contains the entire result. <xref |
327 |
| - linkend="jdbc-query-example"> illustrates this process. |
| 326 | + instance, which contains the entire result (see <xref linkend="jdbc-query-with-cursor"> |
| 327 | + here for how to alter this behaviour). |
| 328 | + <xref linkend="jdbc-query-example"> illustrates this process. |
328 | 329 | </para>
|
329 | 330 |
|
330 | 331 | <example id="jdbc-query-example">
|
@@ -364,6 +365,50 @@ st.close();
|
364 | 365 | </para>
|
365 | 366 | </example>
|
366 | 367 |
|
| 368 | + <sect2 id="query-with-cursor"> |
| 369 | + <title>Getting results based on a cursor</title> |
| 370 | + |
| 371 | + <para>By default the driver collects all the results for the |
| 372 | + query at once. This can be inconvieniant for large data sets so |
| 373 | + the JDBC driver provides a means of basing |
| 374 | + a <classname>ResultSet</classname> on a database cursor and |
| 375 | + only fetching a small number of rows.</para> |
| 376 | + |
| 377 | + <para>A small number of rows are cached on the |
| 378 | + client side of the connection and when exhausted the next |
| 379 | + block of rows is retrieved by repositioning the cursor. |
| 380 | + </para> |
| 381 | + |
| 382 | + <example> |
| 383 | + <title>Setting fetch size to turn cursors on and off.</title> |
| 384 | + |
| 385 | + <para>Changing code to cursor mode is as simple as setting the |
| 386 | + fetch size of the <classname>Statement</classname> to the |
| 387 | + appropriate size. Setting the fetch size back to 0 will cause |
| 388 | + all rows to be cached (the default behaviour). |
| 389 | + |
| 390 | +<programlisting> |
| 391 | +Statement st = db.createStatement(); |
| 392 | +// Turn use of the cursor on. |
| 393 | +st.setFetchSize(50); |
| 394 | +ResultSet rs = st.executeQuery("SELECT * FROM mytable"); |
| 395 | +while (rs.next()) { |
| 396 | + System.out.print("a row was returned."); |
| 397 | +} |
| 398 | +rs.close(); |
| 399 | +// Turn the cursor off. |
| 400 | +st.setFetchSize(0); |
| 401 | +ResultSet rs = st.executeQuery("SELECT * FROM mytable"); |
| 402 | +while (rs.next()) { |
| 403 | + System.out.print("many rows were returned."); |
| 404 | +} |
| 405 | +rs.close(); |
| 406 | +// Close the statement. |
| 407 | +st.close(); |
| 408 | +</programlisting> |
| 409 | + </para> |
| 410 | + |
| 411 | + |
367 | 412 | <sect2>
|
368 | 413 | <title>Using the <classname>Statement</classname> or <classname>PreparedStatement</classname> Interface</title>
|
369 | 414 |
|
@@ -494,6 +539,120 @@ st.close();
|
494 | 539 | </example>
|
495 | 540 | </sect1>
|
496 | 541 |
|
| 542 | + |
| 543 | + <sect1 id="jdbc-callproc"> |
| 544 | + <title>Calling Stored Functions</title> |
| 545 | + |
| 546 | + <para><productname>PostgreSQL's</productname> jdbc driver fully |
| 547 | + supports calling <productname>PostgreSQL</productname> stored |
| 548 | + functions.</para> |
| 549 | + |
| 550 | + <example id="jdbc-call-function"> |
| 551 | + <title>Calling a built in stored function</title> |
| 552 | + |
| 553 | + <para>This example shows how to call |
| 554 | + a <productname>PostgreSQL</productname> built in |
| 555 | + function, <command>upper</command>, which simply converts the |
| 556 | + supplied string argument to uppercase. |
| 557 | + |
| 558 | +<programlisting> |
| 559 | +// Turn transactions off. |
| 560 | +con.setAutoCommit(false); |
| 561 | +// Procedure call. |
| 562 | +CallableStatement upperProc = con.prepareCall("{ ? = call upper( ? ) }"); |
| 563 | +upperProc.registerOutParameter(1, Types.VARCHAR); |
| 564 | +upperProc.setString(2, "lowercase to uppercase"); |
| 565 | +upperProc.execute(); |
| 566 | +String upperCased = upperProc.getString(1); |
| 567 | +upperProc.close(); |
| 568 | +</programlisting> |
| 569 | + </para> |
| 570 | + </example> |
| 571 | + |
| 572 | + <sect2> |
| 573 | + <title>Using the <classname>CallableStatement</classname> Interface</title> |
| 574 | + |
| 575 | + <para> |
| 576 | + All the considerations that apply |
| 577 | + for <classname>Statement</classname> |
| 578 | + and <classname>PreparedStatement</classname> apply |
| 579 | + for <classname>CallableStatement</classname> but in addition |
| 580 | + you must also consider one extra restriction: |
| 581 | + </para> |
| 582 | + |
| 583 | + <itemizedlist> |
| 584 | + <listitem> |
| 585 | + <para>You can only call a stored function from within a |
| 586 | + transaction.</para> |
| 587 | + </listitem> |
| 588 | + </itemizedlist> |
| 589 | + |
| 590 | + </sect2> |
| 591 | + |
| 592 | + <sect2> |
| 593 | + <title>Obtaining <classname>ResultSet</classname> from a stored function</title> |
| 594 | + |
| 595 | + <para><productname>PostgreSQL's</productname> stored function |
| 596 | + can return results by means of a <type>refcursor</type> |
| 597 | + value. A <type>refcursor</type>.</para> |
| 598 | + |
| 599 | + <para>As an extension to JDBC, |
| 600 | + the <productname>PostgreSQL</productname> JDBC driver can |
| 601 | + return <type>refcursor</type> values |
| 602 | + as <classname>ResultSet</classname> values.</para> |
| 603 | + |
| 604 | + <example id="get-refcursor-from-function-call"> |
| 605 | + <title>Gettig <type>refcursor</type> values from a |
| 606 | + function</title> |
| 607 | + |
| 608 | + <para>When calling a function that returns |
| 609 | + a <type>refcursor</type> you must cast the return type |
| 610 | + of <methodname>getObject</methodname> to |
| 611 | + a <classname>ResultSet</classname></para> |
| 612 | + |
| 613 | +<programlisting> |
| 614 | +// Turn transactions off. |
| 615 | +con.setAutoCommit(false); |
| 616 | +// Procedure call. |
| 617 | +CallableStatement proc = con.prepareCall("{ ? = call doquery ( ? ) }"); |
| 618 | +proc.registerOutParameter(1, Types.Other); |
| 619 | +proc.setInt(2, -1); |
| 620 | +proc.execute(); |
| 621 | +ResultSet results = (ResultSet) proc.getObject(1); |
| 622 | +while (results.next()) { |
| 623 | + // do something with the results... |
| 624 | +} |
| 625 | +results.close(); |
| 626 | +proc.close(); |
| 627 | +</programlisting> |
| 628 | + </example> |
| 629 | + |
| 630 | + <para>It is also possible to treat the <type>refcursor</type> |
| 631 | + return value as a distinct type in itself. The JDBC driver |
| 632 | + provides |
| 633 | + the <classname>org.postgresql.PGRefCursorResultSet</classname> |
| 634 | + class for this purpose.</para> |
| 635 | + |
| 636 | + <example> |
| 637 | + <title>Treating <type>refcursor</type> as a distinct |
| 638 | + type</title> |
| 639 | + |
| 640 | +<programlisting> |
| 641 | +con.setAutoCommit(false); |
| 642 | +CallableStatement proc = con.prepareCall("{ ? = call doquery ( ? ) }"); |
| 643 | +proc.registerOutParameter(1, Types.Other); |
| 644 | +proc.setInt(2, 0); |
| 645 | +org.postgresql.PGRefCursorResultSet refcurs |
| 646 | + = (PGRefCursorResultSet) con.getObject(1); |
| 647 | +String cursorName = refcurs.getRefCursor(); |
| 648 | +proc.close(); |
| 649 | +</programlisting> |
| 650 | + </example> |
| 651 | + </sect2> |
| 652 | + |
| 653 | + </sect1> |
| 654 | + |
| 655 | + |
497 | 656 | <sect1 id="jdbc-ddl">
|
498 | 657 | <title>Creating and Modifying Database Objects</title>
|
499 | 658 |
|
|
0 commit comments