显示标签为“DataBase”的博文。显示所有博文
显示标签为“DataBase”的博文。显示所有博文

星期三, 六月 06, 2007

关于几种不同的IDENTITY(SQLSERVER)


SCOPE_IDENTITY、IDENT_CURRENT   和   @@IDENTITY  
三者在功能上相似,因为它们都返回插入到   IDENTITY   列中的值。    
   
  IDENT_CURRENT   不受作用域和会话的限制,而受限于指定的表。IDENT_CURRENT   返回为任何会话和作用域中的特定表所生成的值。有关更多信息,请参见   IDENT_CURRENT。  
   
  SCOPE_IDENTITY   和   @@IDENTITY   返回在当前会话中的任何表内所生成的最后一个标识值。但是,SCOPE_IDENTITY   只返回插入到当前作用域中的值;@@IDENTITY   不受限于特定的作用域。  
   
  例如,有两个表   T1   和   T2,在   T1   上定义了一个   INSERT   触发器。当将某行插入   T1   时,触发器被激发,并在   T2   中插入一行。此例说明了两个作用域:一个是在   T1   上的插入,另一个是作为触发器的结果在   T2   上的插入。  
假设   T1   和   T2   都有   IDENTITY   列,@@IDENTITY   和   SCOPE_IDENTITY   将在   T1   上的   INSERT   语句的最后返回不同的值。  
   
  @@IDENTITY   返回插入到当前会话中任何作用域内的最后一个   IDENTITY   列值,该值是插入   T2   中的值。  
   
  SCOPE_IDENTITY()   返回插入   T1   中的   IDENTITY   值,该值是发生在相同作用域中的最后一个   INSERT。如果在作用域中发生插入语句到标识列之前唤醒调用   SCOPE_IDENTITY()   函数,则该函数将返回   NULL   值。  

星期五, 六月 01, 2007

db2 sample address

参考地址:
 
 
 
 
 
Java サンプル・プログラム
 
  • UNIX の場合:
    sqllib/samples/java
    すべてのサブディレクトリー内の Java サンプル・プログラムの README ファイルが入っています。
    sqllib/samples/java/jdbc
    JDBC サンプル・プログラム・ファイルが入っています。
    sqllib/samples/java/sqlj
    SQLJ サンプル・プログラムが入っています。
    sqllib/samples/xml/java
    JDBC および SQLJ XML サンプルのサブディレクトリーが入っています。
    sqllib/samples/xml/java/jdbc
    README ファイルと JDBC XML サンプル・プログラムが入っています。
    sqllib/samples/xml/java/sqlj
    README ファイルと SQLJ XML サンプル・プログラムが入っています。
    sqllib/samples/java/Websphere
    WebSphere サンプル・プログラムが入っています。
    sqllib/samples/java/plugin
    DB2 コントロール・センターのプラグイン例のファイルが入っています。
    sqllib/samples/java/plugin/doc
    プラグイン・インターフェース用の javadoc ファイルが入っています。
  • Windows の場合;
    sqllib¥samples¥java
    すべてのサブディレクトリー内の Java サンプル・プログラムの README ファイルが入っています。
    sqllib¥samples¥java¥jdbc
    JDBC サンプル・プログラムが入っています。
    sqllib¥samples¥java¥sqlj
    SQLJ サンプル・プログラムが入っています。
    sqllib¥samples¥xml¥java
    JDBC および SQLJ XML サンプルのサブディレクトリーが入っています。
    sqllib¥samples¥xml¥java¥jdbc
    README ファイルと JDBC XML サンプル・プログラムが入っています。
    sqllib¥samples¥xml¥java¥sqlj
    README ファイルと SQLJ XML サンプル・プログラムが入っています。
    sqllib¥samples¥java¥Websphere
    WebSphere サンプル・プログラムが入っています。
    sqllib¥samples¥java¥plugin
    DB2 コントロール・センターのプラグイン例のファイルが入っています。
    sqllib¥samples¥java¥plugin¥doc
    プラグイン・インターフェース用の javadoc ファイルが入っています。
  •  

    java调用db2管理API——export,Import

     
    import java.io.*;    
    import java.lang.*;
    import java.util.*;
    import java.sql.*;

    class AdmCmdExport
    {

      public static void main(String argv[])
      {
        Connection con = null;
       
        int rows_exported;
        String msg_retrieval = null;
        String msg_removal = null;
        String sqlcode = null;
        String msg = null;
       
        CallableStatement callStmt1 = null;
        ResultSet rs1 = null;
        PreparedStatement stmt1 = null;
        ResultSet rs2 = null;
        CallableStatement callStmt2 = null;

        if (argv.length < 1)
        {
          System.out.println("\n Usage : java AdmCmdExport <path for export>");
        }
        else
        {            
          try
          {
            // initialize DB2Driver and establish database connection.
            COM.ibm.db2.jdbc.app.DB2Driver db2Driver =
              (COM.ibm.db2.jdbc.app.DB2Driver )
                Class.forName("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();
            con = DriverManager.getConnection("jdbc:db2:SAMPLE");

            System.out.println("HOW TO PERFORM EXPORT USING ADMIN_CMD.\n");
            // prepare the CALL statement for OUT_LANGUAGE
            String sql = "CALL SYSPROC.ADMIN_CMD(?)";
            callStmt1 = con.prepareCall(sql);

            String param = "export to "+ argv[0] + "org_ex.ixf ";
            param = param + "of ixf messages on server select * from org" ;

            // set the imput parameter
            callStmt1.setString(1, param);
            System.out.println("CALL ADMIN_CMD('" + param + "')");
          
            // execute export by calling ADMIN_CMD
            callStmt1.execute();
            rs1 = callStmt1.getResultSet();
            // retrieve the resultset 
            if( rs1.next())
            {
              // the numbers of rows exported
              rows_exported = rs1.getInt(1);

              // retrieve the select stmt for message retrival
              // containing SYSPROC.ADMIN_GET_MSGS
              msg_retrieval = rs1.getString(2);
     
              // retrive the stmt for message cleanup
              // containing CALL of SYSPROC.ADMIN_REMOVE_MSGS
              msg_removal = rs1.getString(3);
         
              // display the output
              System.out.println("Total number of rows exported  : " + rows_exported);
              System.out.println("SQL for retrieving the messages: " + msg_retrieval);
              System.out.println("SQL for removing the messages  : " + msg_removal);
            }
         
            stmt1 = con.prepareStatement(msg_retrieval);
            System.out.println("\n" + "Executing " + msg_retrieval); 

            // message retrivel
            rs2 = stmt1.executeQuery();

            // retrieve the resultset
            while(rs2.next())
            {
              // retrieve the sqlcode
        sqlcode = rs2.getString(1);
         
              // retrieve the error message
              msg = rs2.getString(2);
              System.out.println ("Sqlcode : " +sqlcode);
              System.out.println("Msg     : " +msg);
            }

            System.out.println("\nExecuting " + msg_removal);
            callStmt2 = con.prepareCall (msg_removal);

            // executing the message retrivel
            callStmt2.execute();     
          }
          catch(Exception e)
          {
            JdbcException jdbcExc = new JdbcException(e);
            jdbcExc.handle ();
          }
          finally
          {
            try
            {
              // close the statements
              callStmt1.close();
              callStmt2.close();
              stmt1.close();

              // close the resultsets
              rs1.close();
              rs2.close();
        
              // roll back any changes to the database made by this sample
              con.rollback();

              // close the connection                                  
              con.close();
            }
            catch (Exception x)
            {
              System.out.print("\n Unable to Rollback/Disconnect ");
              System.out.println("from 'sample' database");
            }
          }
        }
      } // main
    } // AdmCmdExport
     
     
    import java.io.*;     //JDBC classes          
    import java.lang.*;
    import java.util.*;
    import java.sql.*;

    class AdmCmdImport
    {

      public static void main(String argv[])
      {
        Connection con = null;
        CallableStatement callStmt1 = null;
        CallableStatement callStmt2 = null;
        ResultSet rs1 = null;
        ResultSet rs2 = null;
        PreparedStatement stmt1 = null;
        Statement stmt2 = null;
     
        int rows_read;
        int rows_skipped;
        int rows_loaded;
        int rows_rejected;
        int rows_deleted;
        int rows_committed;

        String msg_retrieval = null;
        String msg_removal = null;
        String sqlcode = null;
        String msg = null;
     
        if (argv.length < 1)
        {
          System.out.println("\n Usage : java AdmCmdImport <path for import>");
        }
        else
        {            
          try
          {
            // Initialize DB2Driver and establish database connection.
            COM.ibm.db2.jdbc.app.DB2Driver db2Driver =
              (COM.ibm.db2.jdbc.app.DB2Driver)
                Class.forName ("COM.ibm.db2.jdbc.app.DB2Driver").newInstance();
            con = DriverManager.getConnection("jdbc:db2:SAMPLE");

            System.out.println("HOW TO DO IMPORT USING ADMIN_CMD.\n");
            // prepare the CALL statement for OUT_LANGUAGE
            String sql = "CALL SYSPROC.ADMIN_CMD(?)";
            callStmt1 = con.prepareCall(sql);

            // argv[0] is the path for the file to be imported
            String param = "IMPORT FROM " + argv[0] + "org_ex.ixf OF IXF MESSAGES ";
            param = param + "ON SERVER CREATE INTO ORG_IMPORT" ;

            // setting the imput parameter
            callStmt1.setString(1, param);
            System.out.println("CALL ADMIN_CMD('" + param + "')");
          
            // executing import by calling ADMIN_CMD
            callStmt1.execute ();
            rs1 = callStmt1.getResultSet();
         
            // retrieving the resultset 
            if( rs1.next())
            {
              // retrieve the no of rows read
              rows_read = rs1.getInt(1);
              // retrieve the no of rows skipped
              rows_skipped = rs1.getInt(2);
              // retrieve the no of rows loaded
              rows_loaded = rs1.getInt(3);
              // retrieve the no of rows rejected
              rows_rejected = rs1.getInt(4);
              // retrieve the no of rows deleted
              rows_deleted = rs1.getInt(5);
              // retrieve the no of rows committed
              rows_committed = rs1.getInt (6);

              // retrieve the select stmt for message retrival
              // containing SYSPROC.ADMIN_GET_MSGS
              msg_retrieval = rs1.getString(7);
     
              // retrive the stmt for message cleanup
              // containing CALL of SYSPROC.ADMIN_REMOVE_MSGS
              msg_removal = rs1.getString(8);
         
              // Displaying the resultset
              System.out.print("\nTotal number of rows read      : ");
              System.out.println(rows_read);
              System.out.print("Total number of rows skipped   : ");
              System.out.println( rows_skipped);
              System.out.print("Total number of rows loaded    : ");
              System.out.println(rows_loaded);
              System.out.print("Total number of rows rejected  : ");
              System.out.println(rows_rejected);
              System.out.print("Total number of rows deleted   : ");
              System.out.println(rows_deleted);
              System.out.print("Total number of rows committed : ");
              System.out.println(rows_read);
              System.out.print("SQL for retrieving the messages: ");
              System.out.println(msg_retrieval);
              System.out.print("SQL for removing the messages  : ");
              System.out.println(msg_removal);
            }
         
            stmt1 = con.prepareStatement (msg_retrieval);
            System.out.println("\n" + "Executing " + msg_retrieval); 

            // message retrivel
            rs2 = stmt1.executeQuery();

            // retrieving the resultset
            while(rs2.next())
            {
              // retrieving the sqlcode
        sqlcode = rs2.getString(1);
         
              //retrieving the error message
              msg = rs2.getString(2);

              System.out.println("Sqlcode : " +sqlcode);
              System.out.println("Msg     : " +msg);
            }

            System.out.println("\n Executing " + msg_removal);
            callStmt2 = con.prepareCall(msg_removal);

            // executing the message retrivel
            callStmt2.execute();     

            System.out.println("\n Executing DROP TABLE ORG_IMPORT");  
            stmt2 = con.createStatement();
            stmt2.executeUpdate("DROP TABLE ORG_IMPORT");
          }
          catch(Exception e)
          {
            JdbcException jdbcExc = new JdbcException(e);
            jdbcExc.handle ();
          }
          finally
          {
            try
            {
              //closing the statements and resultset   
              callStmt1.close();
              callStmt2.close();
              stmt1.close();
              stmt2.close();
              rs1.close();
              rs2.close();
        
              // roll back any changes to the database made by this sample
              con.rollback();

              // closing the connection                                  
              con.close();
            }
            catch (Exception x)
            {
              System.out.print(x);
              System.out.print("\n Unable to Rollback/Disconnect ");
              System.out.println ("from 'sample' database");
            }
          }
        }
      } // main
    } // AdmCmdImport

    星期五, 五月 18, 2007

    Java SE 6中JDBC 4.0的增强特性(转)

    摘要:

    Java SE 6包含了对Java数据库互连(JDBC)API的一些增强特性。这些增强特性的版本将定为JDBC version 4.0。JDBC新特性的目的是提供更简单的设计和更好的开发体验。本文将概述JDBC 4.0的增强特性和为企业级Java开发人员带来的好处。我们将通过一个用Apache Derby作为后台数据库的贷款处理应用范例来探究JDBC的新特性。

    Java SE 6包含了对Java数据库互连(JDBC)API的一些增强特性。这些增强特性的版本将定为JDBC version 4.0。JDBC新特性的目的是提供更简单的设计和更好的开发体验。本文将概述JDBC 4.0的增强特性和为企业级Java开发人员带来的好处。我们将通过一个用Apache Derby作为后台数据库的贷款处理应用范例来探究JDBC的新特性。

    Java SE 6.0
    Java SE 6.0版以兼容性、稳定性和品质作为设计目标。本版本中有不少值得关注的增强特性,特别是JMX、web services、脚本语言支持(采用Rhino脚本引擎JSR 223把JavaScript技术与Java源码进行集成)、数据库连接、支持annotations和安全部分。另外,在JDBC API中还有不少新的特性,包括RowId支持和新增的SQLException子类。

    JDBC 4.0的特性
    得益于Mustang中的Java SE 服务提供商机制,Java开发人员再也不必用类似Class.forName()的代码注册JDBC驱动来明确加载JDBC。当调用DriverManager.getConnection()方法时,DriverManager类将自动设置合适的驱动程序。该特性向后兼容,因此无需对现有的JDBC代码作任何改动。

    通过对Java应用程序访问数据库代码的简化,使得JDBC 4.0有更好的开发体验。JDBC 4.0同时也提供了工具类来改进数据源和连接对象的管理,也改进了JDBC驱动加载和卸载机制。

    有了JDBC 4.0传承自Java SE 5.0 (Tiger)版对元数据的支持功能,Java开发人员可用Annotations明确指明SQL查询。基于标注的SQL查询允许我们通过在Java代码中使用Annotation关键字正确指明SQL查询字符串。这样,我们不必查看JDBC代码和他所调用的数据库两份不同的文件。例如,用一个名为getActiveLoans()方法在贷款处理数据库中获取一个活跃贷款清单,你可以添加@Query(sql="SELECT * FROM LoanApplicationDetails WHERE LoanStatus = 'A'")标注来修饰该方法。

    并且,最终版的Java SE 6开发包(JDK 6)以及其相应的执行期环境(JRE 6)会捆绑一个基于Apache Derby的数据库。这使得Java开发人员无需下载、安装和配置一款单独的数据库产品就能探究JDBC的新特性。

    JDBC 4.0中增加的主要特性包括:
    1.        JDBC驱动类的自动加载
    2.        连接管理的增强
    3.        对RowId SQL类型的支持
    4.        SQL的DataSet实现使用了Annotations
    5.        SQL异常处理的增强
    6.        对SQL XML的支持

    另外,对BLOB/CLOB 的改进支持以及对国际字符集的支持也是JDBC 4.0的特性。这些特性将在随后章节中详细讨论。

    JDBC驱动自动加载
    在JDBC 4.0中,我们不必再使用Class.forName()方法明确加载JDBC驱动。当调用getConnection方法时,DriverManager会尝试从初始化时已经加载的JDBC驱动程序库中选择合适的驱动,以及他在当前应用的同一个类加载器中明确加载使用过的驱动。
    DriverManager中的getConnection和getDrivers方法已作了改进,以支持Java SE 服务提供商机制(SPM)。根据SPM,所谓服务就是一组广为人知的接口和抽象类的集合,而服务提供商就是对某一服务的特定实现。SPM还指明了服务提供商的配置文件存放于META-INF/services目录下。JDBC 4.0的驱动程序库必须包含META-INF/services/java.sql.Driver文件。该文件包含对java.sql.Driver 实现的JDBC驱动文件名。例如,通过JDBC驱动连接Apache Derby数据库,META-INF/services/java.sql.Driver将含有以下路径:
    org.apache.derby.jdbc.EmbeddedDriver

    我们再来快速地看一下如何使用这一新特性加载一个JDBC驱动管理。以下显示的是我们用以加载JDBC驱动的典型范例代码。这里我们假设连接的是Apache Derby数据库,因为该数据库将在本文随后的范例应用中用到:
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        Connection conn =
            DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
    但在JDBC 4.0中,我们不必写Class.forName()这一行,我们只需要调用getConnection()方法取得数据库连接。
    请注意,仅在完全独立的模式下可使用该方法取得数据库的连接。如果你使用一些类似数据库连接池等技术管理连接,那么代码将有所不同。

    连接管理
    在JDBC 4.0之前,我们依靠JDBC URL来定义一个数据源连接。现在有了JDBC 4.0,我们只需为标准连接工厂机制提供一组参数,就能获取与任何数据源的连接。Connection和Statement接口增添的新方法为池环境中管理Statement对象提供了更好的连接状态跟踪机制和更大的灵活度。元数据工具(JSR-175)被用来管理活跃连接。我们还能获得元数据信息,如:活跃连接状态,并能指明XA事务的某一连接是标准式(Connection,在独立应用的情况下)、池式(PooledConnection)还是分布式(XAConnection)。该接口仅在诸如WebLogic、WebSphere和JBoss等Java EE应用服务器的事务管理中使用。

    RowId支持
    JDBC 4.0增加了RowID接口以支持ROWID数据类型,Oracle和DB2数据库支持该数据类型。在你需要把大量缺少唯一标识符字段的查询记录放入一个不允许重复对象的Collection容器(如Hashtable)的情况下,RowId很有用。我们可以用ResultSet的getRowId()方法获取RowId,用PreparedStatement的setRowId()方法在查询中使用RowId。

    关于RowId对象需要记住的一件重要事项是,RowId值在数据源之间不可移植。当在PreparedStatement和ResultSet中单独使用set或update方法时,需要想到指明数据源。因此,RowId对象不应被不同的Connection和ResultSet对象共享。

    DatabaseMetaData中的getRowIdLifetime()方法可被用来确定RowId对象的有效存活时间。该方法的可能返回值如表1所列:
    RowId值                                          描述
    ROWID_UNSUPPORTED        Doesn't support ROWID data type.
    ROWID_VALID_OTHER        Lifetime of the RowID is dependent on database vendor implementation.
    ROWID_VALID_TRANSACTION        Lifetime of the RowID is within the current transaction as long as the row in the database table is not deleted.
    ROWID_VALID_SESSION        Lifetime of the RowID is the duration of the current session as long as the row in the database table is not deleted.
    ROWID_VALID_FOREVER        Lifetime of the RowID is unlimited as long as the row in the database table is not deleted.

    基于标注的SQL查询
    JDBC 4.0对标注(Java SE 5新增)作了进一步规范和补充,他允许开发人员不必再写大量代码就能达到联系SQL查询和Java类的目的。并且,通过使用Generics(JSR 014)和元数据(JSR 175) API,我们只要指明查询的输入和输出参数就能将SQL查询与Java对象进行关联。我们还可以将查询结果捆绑在Java类上以加快查询输出的处理。将查询对象置于Java对象之中,我们可以不必像往常一样写所有代码。在Java代码中指明SQL查询,经常用到两种标注:

    Select标注
    Select标注用于在Java类中指明一个选择查询,使get方法能从数据库表中取回数据。表2显示的是Select标注的不同属性及其作用:
    变量                                           类型        描述
    sql                                                            String        SQL Select query string.
    value                                                            String        Same as sql attribute.
    tableName                                            String        Name of the database table against which the sql will be invoked.
    readOnly, connected, scrollable            Boolean        Flags used to indicate if the returned DataSet is read-only or updateable, is connected to the back-end database, and is scrollable when used in connected mode respectively.
    allColumnsMapped                                            Boolean        Flag to indicate if the column names in the sql annotation element are mapped 1-to-1 with the fields in the DataSet.

    这里有一个应用Select标注从贷款数据库中获取所有活跃贷款的例子:
    interface LoanAppDetailsQuery extends BaseQuery {
            @Select("SELECT * FROM LoanDetais where LoanStatus = 'A'")
            DataSet<LoanApplication> getAllActiveLoans();
    }

    Sql标注同样允许I/O参数(参数标记以一个问号后跟一个整型数据表示)。这里是一个参数化sql查询的例子:
    interface LoanAppDetailsQuery extends BaseQuery {
            @Select(sql="SELECT * from LoanDetails
                    where borrowerFirstName= ?1 and borrowerLastName= ?2")
            DataSet<LoanApplication> getLoanDetailsByBorrowerName(String borrFirstName,
                    String borrLastName);
    }

    Update标注
    Update标注用于修饰Query接口方法以更新数据库表中的一条或多条记录。Update标注必须包含一个sql标注类型元素。这里是一个Update标注的例子:
    interface LoanAppDetailsQuery extends BaseQuery {
            @Update(sql="update LoanDetails set LoanStatus = ?1
                    where loanId = ?2")
            boolean updateLoanStatus(String loanStatus, int loanId);
    }

    SQL异常处理的增强特性
    异常处理是Java编程的一个重要部分,特别是对后台关系数据库进行连接或查询时。SQLException是我们用以指出与数据库相关错误的类。JDBC 4.0在SQLException处理中有不少增强。为了在处理SQLException时获得更好的开发体验,JDBC 4.0版作了如下增强:
    1.        新的SQLException子类
    2.        对因果关系的支持
    3.        对改进的for-each循环的支持

    新的SQLException类
    SQLException的新子类提供了一种方法,使Java开发人员能写出更方便改动的错误处理代码。JDBC 4.0介绍了两个新的SQLException型别:
    •        SQL non-transient exception
    •        SQL transient exception

    Non-Transient Exception:除非修正引发SQLException异常的代码,否则该异常在再次尝试相同JDBC操作失败后被抛出。表3显示了JDBC 4.0新增的SQLNonTransientException异常子类(SQL 2003规范中定义了SQLState类的值):

    Exception class                                         SQLState value
    SQLFeatureNotSupportedException          0A
    SQLNonTransientConnectionException     08
    SQLDataException                                           22
    SQLIntegrityConstraintViolationException        23
    SQLInvalidAuthorizationException             28
    SQLSyntaxErrorException                            42

    Transient Exception:当先前执行失败的JDBC操作在没有任何应用级功能干涉的情况下可能成功执行时,该异常被抛出。继承自SQLTransientException的新异常如表4所列:

    Exception class                                SQLState value
    SQLTransientConnectionException        08
    SQLTransactionRollbackException        40
    SQLTimeoutException                      None

    因果关系
    SQLException类现在支持Java SE链式异常机制(又称因果工具),它使我们能在一个JDBC操作中处理多条SQLException异常(如果后台数据库支持多条异常特性)。这种情形发生在执行一条可能会抛出多条SQLException异常的语句时。

    我们可以调用SQLException中的getNextException()方法在异常链中进行迭代。这里是一些处理getNextException()因果关系的范例代码:
    catch(SQLException ex) {
         while(ex != null) {
            LOG.error("SQL State:" + ex.getSQLState());
            LOG.error("Error Code:" + ex.getErrorCode());
            LOG.error("Message:" + ex.getMessage());
            Throwable t = ex.getCause();
            while(t != null) {
                LOG.error("Cause:" + t);
                t = t.getCause();
            }
            ex = ex.getNextException();
        }
    }

    增强的For-Each环
    Java SE 5中,SQLException类通过实现Iterable接口,增加了for-each循环支持的特性。这个循环的轨迹将会包括SQLException和其异常成因。这里的代码片断展示了SQLException中增加的增强型for-each环特性。
    catch(SQLException ex) {
         for(Throwable e : ex ) {
            LOG.error("Error occurred: " + e);
         }
    }

    对国际字符集转换的支持
    以下是JDBC类处理国际字符集的新增特性:
    1.        JDBC数据类型:新增NCHAR、NVARCHAR、LONGNVARCHAR和NCLOB数据类型。
    2.        PreparedStatement:新增setNString、setNCharacterStream和setNClob方法。
    3.        CallableStatement:新增getNClob、getNString和getNCharacterStream方法。
    4.        ResultSet:ResultSet接口新增updateNClob、updateNString和updateNCharacterStream方法。

    对大对象(BLOBs and CLOBs)支持的改进
    以下是JDBC 4.0处理LOBs的新增特性:
    1.        Connection:新增方法(createBlob()、createClob()和createNClob())以创建BLOB、CLOB和NCLOB对象新实例。
    2.        PreparedStatement:新增方法setBlob()、setClob()和setNClob()以使用InputStream对象插入BLOB对象,使用Reader对象插入CLOB和NCLOB对象。
    3.        LOBs:在Blob、Clob和NClob接口中新增方法(free())以释放这些对象所持有的资源。
    现在,让我们来看一看java.sql和javax.jdbc包的新类,以及他们所提供的服务。

    JDBC 4.0 API:新类
    RowId (java.sql)
    正如先前所介绍的,该接口是对数据库中SQL ROWID值的展示。ROWID是一种SQL内建的数据类型,用来标识数据库中的一行特定数据。ROWID经常用于从表中返回查询结果,而这些结果行往往缺少唯一ID字段。

    getRowId和setRowId等CallableStatement、PreparedStatement和ResultSet接口的方法允许程序员访问SQL ROWID值。RowId接口还提供了一个方法(叫getBytes())把ROWID值作为一个byte型数组返回。DatabaseMetaData接口有一个名为getRowIdLifetime的新方法,用以确定某一RowId对象的存活时间。RowId的存活时间范围可以是如下三种类型:
    1.        创建RowId的数据库事务持续时间
    2.        创建RowId的会话持续时间
    3.        数据库对应的记录还未被删除的持续时间

    DataSet (java.sql)
    DataSet接口提供了对执行SQL Query后所返回数据类型的安全检查。DataSet还可以运行在连接或非连接模式。在连接模式下,DataSet类似于ResultSet的功能;而在非连接模式下,他类似于CachedRowSet的功能。由于DataSet继承自List接口,因此我们能对查询返回的记录行进行迭代。

    对已有的类,JDBC 4.0也新增了不少方法。比如,Connection新增了createSQLXML和createSQLXML方法,ResultSet新增了getRowId方法。

    范例应用
    本文所示的范例应用是一个贷款处理应用软件,他有一个贷款搜索页面,用户可以通过输入贷款ID提交查询表,以获取贷款详情。贷款搜索页面调用一个控制器对象,而该对象又调用一个DAO对象访问后台数据库,以取回贷款详情。这些详情包括贷款人、贷款数额、贷款截至日期等信息,并显示在贷款详情屏幕上。后台数据库中,我们有一个名为LoanApplicationDetails的表,来存储贷款软件的详情。

    该范例应用的用例是通过指定贷款ID来获取贷款详情。当贷款已经登记并将抵押物与利息挂钩后,贷款详情就可以被获取。表5显示了贷款处理应用软件项目的详情。
    Name                            Value
    Project Name        JdbcApp
    Project Directory        c:\dev\projects\JdbcApp
    DB Directory        c:\dev\dbservers\apache\derby
    JDK Directory        c:\dev\java\jdk_1.6.0
    IDE Directory        c:\dev\tools\eclipse
    Database        Apache Derby 10.1.2.1
    JDK                        6.0 (beta 2 release)
    IDE                        Eclipse 3.1
    Unit Testing        JUnit 4
    Build                        Ant 1.6.5

    下表所列的是我们连接贷款详情Apache Derby数据库所需的JDBC参数。这些参数存放于一个名为derby.properties的文本文件中,并置于项目的etc/jdbc目录下(见表6)。

    Name                           Value
    JDBC Driver File        LoanApp\META-INF\services\java.sql.driver
    Driver                       org.apache.derby.ClientDriver
    URL                       jdbc:derby:derbyDB
    User Id                       user1
    Password                       user1

    请注意:Apache Derby数据库提供了两种JDBC驱动:嵌入式驱动(org.apache.derby.jdbc.EmbeddedDriver)和客户端/服务器驱动(org.apache.derby.jdbc.ClientDriver)。我在范例应用中使用客户端/服务器版驱动。
    以下是使用ij工具来启动Derby数据库服务器并创建新数据库的命令。

    要启动Derby网络服务器,需开启一个命令行窗口,并运行如下命令(请根据你本机的环境改写DERBY_INSTALL和JAVA_HOME环境变量)。
    set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.2.1-bin
    set JAVA_HOME=C:\dev\java\jdk1.6.0
    set DERBY_INSTALL=C:\dev\dbservers\db- derby-10.1.3.1-bin
    set CLASSPATH=%CLASSPATH%;%DERBY_INSTALL%\lib\derby.jar;
                    %DERBY_INSTALL%\lib\derbytools.jar;
                    %DERBY_INSTALL%\lib\derbynet.jar;

    cd %DERBY_INSTALL%\frameworks\NetworkServer\bin
    startNetworkServer.bat

    要连接数据库服务器并创建测试数据库,需开启另一个命令行窗口并运行以下命令。请确保DERBY_INSTALL和JAVA_HOME环境变量符合你本机的环境。
    set JAVA_HOME=C:\dev\java\jdk1.6.0
    set DERBY_INSTALL=C:\dev\dbservers\db-derby-10.1.3.1-bin
    set CLASSPATH=%DERBY_INSTALL%\lib\derbyclient.jar;
                    %DERBY_INSTALL%\lib\derbytools.jar;.

    %JAVA_HOME%\bin\java org.apache.derby.tools.ij
    connect 'jdbc:derby://localhost:1527/LoanDB;create=true';

    测试
    要编译Java源代码,classpath需包括derby.jar和junit4.jar文件,这两个文件在项目的lib目录下。Classpath还需包括etc、etc/jdbc和etc/log4j目录,这样应用程序才能访问JDBC属性文件和Log4J配置文件。我创建了一个Ant构建脚本(在JdbcApp/build目录下)来自动完成编译和打包Java源代码的工作。

    用于测试贷款详情数据库访问对象的测试类名为LoanAppDetailsDAOTest。我们传入贷款ID和贷款人参数就可以获取贷款详情。
    以下部分显示了JDBC 4.0中自动加载JDBC驱动和基于标注的SQL查询特性的代码范例。

    JDBC驱动的自动加载
    BaseDAO抽象类有一个名为getConnection的方法用以获得一个数据库连接。以下代码片断显示了该方法(注意,我们不必注册JDBC驱动)。只要java.sql.Driver文件中有合适的驱动程序类名(org.apache.derby.jdbc.ClientDriver ),JDBC驱动将被自动加载。
    protected Connection getConnection() throws DAOException {
            // Load JDBC properties first
            if (jdbcUrl == null || jdbcUser == null ||
                            jdbcPassword == null) {
                    loadJdbcProperties();
            }
            // Get Connection
            Connection conn = null;
            try {
                    conn = DriverManager.getConnection(jdbcUrl, jdbcUser,
                                    jdbcPassword);
            } catch (SQLException sqle) {
                    throw new DAOException("Error in getting a DB connection.",
                                    sqle);
            }
            return conn;
    }

    SQL标注
    LoanAppDetailsQuery接口有标注了的SQL查询,用以获取活跃贷款清单(criteria is loanstatus="A")和某贷款人的贷款详情(在一个贷款人有多笔贷款的情况下)。在上文中,我们已经了解过了这些SQL标注。这里的范例代码显示了我们如何使用标注来调用已定义的SQL查询。
    public DataSet<LoanAppDetails> getAllActiveLoans() throws Exception {
            // Get Connection
            Connection conn = getConnection();
            LoanAppDetailsQuery query = null;
            DataSet<LoanAppDetails> loanDetails = null;
            query = QueryObjectFactory.createQueryObject (
                            LoanAppDetailsQuery.class, conn);
            loanDetails = query.getAllActiveLoans();
            return loanDetails;
    }

    public DataSet<LoanAppDetails> getLoanDetailsByBorrowerName(
                    String borrFirstName, String borrLastName) throws Exception {
            // Get Connection
            Connection conn = getConnection();
            LoanAppDetailsQuery query = null;
            DataSet<LoanAppDetails> loanDetails = null;
            query = QueryObjectFactory.createQueryObject(
                            LoanAppDetailsQuery.class, conn);
            loanDetails = query.getLoanDetailsByBorrowerName(
                            borrFirstName,borrLastName);
            return loanDetails;
    }

    结论
    JDBC 4.0在SQL方面为开发者提供了更好的开发体验。JDBC 4.0的另一个目标是为API增加更丰富的工具以提供企业级JDBC特性管理JDBC资源。并且,JDBC 4.0 API还提供了JDBC驱动的移植方式,使其符合J2EE连接器架构(JCA)规范。这为JDBC厂商提供了向JDBC连接器迁移的能力。在面向企业服务的架构(SPA)中使用JDBC数据源,该移植方式很重要。在SOA中,JDBC数据源可被部署在另一个企业服务总线(ESB)架构内,而不需要为JDBC数据源另写一份ESB实现代码。

    本文中,我们了解了RowId支持,JDBC驱动加载和基于标注的SQL等JDBC 4.0的增强特性。未来,JDBC 4.0还将增加更多特性以支持SQL:2003。请参阅特性文档,以获取更多有关JDBC 4.0特性的信息。

    Resources
    Matrix-与Java共舞
    Sample Application Code

    Srini Penchikala是Flagstar Bank的一位信息系统问题专家。
     

    星期五, 四月 20, 2007

    jdbc 连接数据库

    为了方便大家查找,整理内容如下:
    1. MySQL(http://www.mysql.com)mm.mysql-2.0.2-bin.jar
    Class.forName( "org.gjt.mm.mysql.Driver" );
    cn = DriverManager.getConnection( "jdbc:mysql://MyDbComputerNameOrIP:3306/myDatabaseName", sUsr, sPwd );

    2. PostgreSQL(http://www.de.postgresql.org)pgjdbc2.jar
    Class.forName( "org.postgresql.Driver" );
    cn = DriverManager.getConnection( "jdbc:postgresql://MyDbComputerNameOrIP/myDatabaseName", sUsr, sPwd );

    3. Oracle(http://www.oracle.com/ip/deploy/database/oracle9i/)classes12.zip
    Class.forName( "oracle.jdbc.driver.OracleDriver" );
    cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd );

    4. Sybase(http://jtds.sourceforge.net)jconn2.jar
    Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" );
    cn = DriverManager.getConnection( "jdbc:sybase:Tds:MyDbComputerNameOrIP:2638", sUsr, sPwd );
    //(Default-Username/Password: "dba"/"sql")

    5. Microsoft SQLServer(http://jtds.sourceforge.net)
    Class.forName( "net.sourceforge.jtds.jdbc.Driver" );
    cn = DriverManager.getConnection( "jdbc:jtds:sqlserver://MyDbComputerNameOrIP:1433/master", sUsr, sPwd );

    6. Microsoft SQLServer(http://www.microsoft.com)
    Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" );
    cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://MyDbComputerNameOrIP:1433;databaseName=master", sUsr, sPwd );

    7. ODBC
    Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
    Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd );

    8.DB2(新添加)
    Class.forName("com.ibm.db2.jdbc.net.DB2Driver");
    String url="jdbc:db2://192.9.200.108:6789/SAMPLE"
    cn = DriverManager.getConnection( url, sUsr, sPwd );

    9.Microsoft SQL Server series (6.5, 7.x and 2000) and Sybase 10

    JDBC Name: jTDS
    URL: http://jtds.sourceforge.net/
    Version: 0.5.1
    Download URL: http://sourceforge.net/project/showfiles.php?group_id=33291

    语法:
    Class.forName("net.sourceforge.jtds.jdbc.Driver ");
    Connection con = DriverManager.getConnection("jdbc:jtds:sqlserver://host:port/database","user","password");
    or
    Connection con = DriverManager.getConnection("jdbc:jtds:sybase://host:port/database","user","password");

    10.Postgresql
    JDBC Name: PostgreSQL JDBC
    URL: http://jdbc.postgresql.org/
    Version: 7.3.3 build 110
    Download URL: http://jdbc.postgresql.org/download.html
    语法:
    Class.forName("org.postgresql.Driver");
    Connection con=DriverManager.getConnection("jdbc:postgresql://host:port/database","user","password");

    11.IBM AS400主机在用的JDBC语法
    有装V4R4以上版本的Client Access Express
    可以在C:\Program Files\IBM\Client Access\jt400\lib
    找到 driver 档案 jt400.zip,并更改扩展名成为 jt400.jar
    语法:
    java.sql.DriverManager.registerDriver (new com.ibm.as400.access.AS400JDBCDriver ());
    Class.forName("com.ibm.as400.access.AS400JDBCConnection");
    con = DriverManager.getConnection("jdbc:as400://IP","user","password");

    12.informix
    Class.forName("com.informix.jdbc.IfxDriver").newInstance();
    String url =
    "jdbc:informix-sqli://123.45.67.89:1533/testDB:INFORMIXSERVER=myserver;
    user=testuser;password=testpassword";
    Lib:jdbcdrv.zip

    Class.forName( "com.sybase.jdbc.SybDriver" )
    url="jdbc:sybase:Tds:127.0.0.1:2638/asademo";
    SybConnection connection= (SybConnection)DriverManager.getConnection(url,"dba","sql");

    13.SAP DB
    Class.forName ("com.sap.dbtech.jdbc.DriverSapDB");
    java.sql.Connection connection = java.sql.DriverManager.getConnection ( "jdbc:sapdb://" + host + "/" + database_name,user_name, password)

    14.InterBase
    String url = "jdbc:interbase://localhost/e:/testbed/database/employee.gdb";
    Class.forName("interbase.interclient.Driver");
    //Driver d = new interbase.interclient.Driver (); /* this will also work if you do not want the line above */
    Connection conn = DriverManager.getConnection( url, "sysdba", "masterkey" );

    15.HSqlDB
    url: http://hsqldb.sourceforge.net/
    driver: org.hsqldb.jdbcDriver
    连接方式有4种,分别为:
    con-str(内存): jdbc:hsqldb.
    con-str(本地): jdbc:hsqldb:/path/to/the/db/dir
    con-str(http): jdbc:hsqldb:http://dbsrv
    con-str(hsql): jdbc:hsqldb:hsql://dbsrv

    星期二, 四月 17, 2007

    DB2 的一些限制

    作为db2的管理员,必备的一些常识:
    DB2的限制

    1. 一個表的最大列數<=1012
    2. 一個視圖的最大列數<=5000
    3. 一行的最大長度(字節)<=32677
    4. 每個分區中表的最大尺寸(千兆字節數)<=512
    5. 每個分區中索引的最大尺寸(千兆字節數)<=512
    6. 每個分區中表的最大行數<=4000000000
    7. 最長索引關鍵字(字節數)<=1024
    8. 一個索引關鍵字中的最大列數<=16
    9. 一個表的最大索引數<=32767或存儲器
    10. 一個SQL語句或視圖中所引用的最大表數<=存儲器
    11. 一個預編譯程序中的最大主機變量申明數<=存儲器
    12. 一個SQL語句中所引用的最大主機變量數<=32767
    13. 用于插入或更新的最大主機變量數(字節數)<=32767
    14. 最長的SQL語句(字節數)<=65535
    15. 一個選擇列表中最大的元素個數<=1012
    16. 一個WHERE或HAVING子句中最多的謂詞個數<=存儲器
    17. 一個GROUP BY子句中最多的列<=1012
    18. 一個GROUP BY子句中所有列的最大總長度(字節數)<=32677
    19. 一個ORDER BY子句中最多的列<=1012
    20. 一個ORDER BY子句中所有列的最大總長度(字節數)<=32677
    21. 一個SQLDA的最大規模(字節數)<=存儲器
    22. 預備語句的最大個數<=存儲器
    23. 一個程序中最多可申明的游標數<=存儲器
    24. 一次可打開的最大的游標數<=存儲器
    25. 一個SMS表空間的最多表數<=65534
    26. 一個表中的最大約束數<=存儲器
    27. 子查詢潛套的最高級別=存儲器
    28. 一個單一查詢中的最大子查詢數=存儲器
    29. 一個INSERT語句中的最多值數<=1012
    30. 一個單一UPDATE語句中SET子語句的最多值數<=1012
    31. 一個唯一約束中所有列的最大數(字節數)<=1024
    32. 一個外鍵中所引用列的最大數<=16
    33. 一個外鍵中所引用列的最大總長數(字節數)<=1024
    34. 一個檢查約束說明的的最大總長數(字節數)<=65535
    35. 一個分區關鍵字中列的最大個數<=500
    36. 一個工作單元中可改變的行的最大個數=存儲器
    37. 包的最大個數=存儲器
    38. 一個語句的最大約束數=存儲器
    39. 一個服務器同時存在用戶的最大個數=64000
    40. 一個存儲過程參數的最大個數=32767
    41. 一個用戶自定義的函數中的最大個數=32767
    42. 級聯觸發器的最大運行深度=16
    43. 同時激活的事件監視器的最大個數=90
    44. 一個常規DMS表空間的最大規模(千兆字節數)<=512
    45. 一個長DMS表空間的最大規模(千兆字節數)<=2
    46. 一個臨時DMS表空間的最大規模(千兆字節數)<=2
    47. 一個實例中可同時使用的最大數据庫數<=256
    48. 一個實例中可同時使用的最大用戶數<=64000
    49. 一個數据庫可同時存在的最大程序數<=1000
    50. 最大分區數<=999
    51. 一個DMS表空間的最大表對象個數<=51000
    52. 最長可變索引關鍵字部分(字節數)<=255
    53. 通過別稱的數據源表或視圖的最大列數<=5000
    54. 一個緩沖池中最多頁數(32BIT)<=524288
    55. 一個緩沖池中最多頁數(64BIT)<=2147483647
    56. 一個數据庫中表空間作多個數為<=4096
    57. 一個結构類型中最多屬性數<=4082


    1. 一個表中的列的最大個數
    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    2. 一行的最大長度
    4KB頁大小的限制=4005
    8KB頁大小的限制=8101
    16KB頁大小的限制=16293
    32KB頁大小的限制=32677

    3. 一個表的每個分區的最大規模(千兆字節)
    4KB頁大小的限制=64
    8KB頁大小的限制=128
    16KB頁大小的限制=256
    32KB頁大小的限制=512

    4. 一個索引的每個分區的最大規模(千兆字節)
    4KB頁大小的限制=64
    8KB頁大小的限制=128
    16KB頁大小的限制=256
    32KB頁大小的限制=512

    5. 一個選擇列表元素的最大個數
    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    6. 一個GROUP BY子語句列的最大個數
    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    7. 一個GROUP BY子語句列的最大長度(字節數)
    4KB頁大小的限制=4005
    8KB頁大小的限制=8101
    16KB頁大小的限制=16293
    32KB頁大小的限制=32677

    8. 一個ORDER BY子語句列的最大個數
    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    9. 一個ORDER BY子語句列的最大長度(字節數)
    4KB頁大小的限制=4005
    8KB頁大小的限制=8101
    16KB頁大小的限制=16293
    32KB頁大小的限制=32677

    10. 一個INSERT語句中數值的最大個數
    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    11. 一個UPDATE語句中數值的最大個數

    4KB頁大小的限制=500
    8KB頁大小的限制=1012
    16KB頁大小的限制=1012
    32KB頁大小的限制=1012

    12. 一個常規DMS表空間的最大規模(千兆字節數)
    4KB頁大小的限制=64
    8KB頁大小的限制=128
    16KB頁大小的限制=256
    32KB頁大小的限制=512


    1. 最小的 DATE 值 = 0001-01-01
    2. 最大的 DATE 值 = 9999-12-31
    3. 最小的 TIME 值 = 00:00:00
    4. 最大的 TIME 值 = 24:00:00
    5. 最小的 TIMESTAMP 值 = 0001-01-01-00:00:00:000000
    6. 最大的 TIMESTAMP 值 = 9999-12-31-24:00:00:000000

    1. CHAR 的最大長度(字節數)<=254
    2. VARCHAR 的最大長度(字節數)<=32672
    3. LONG VARCHAR 的最大長度(字節數)<=32700
    4. CLOB 的最大長度(字節數)<=2147483647
    5. GRAPHICCHAR 的最大長度(字節數)<=127
    6. VARGRAPHIC 的最大長度(字節數)<=16336
    7. LONG VARGRAPHIC 的最大長度(字節數)<=16350
    8. DBCLOB 的最大長度(字節數)<=1073741823
    9. BLOB 的最大長度(字節數)<=2147483647
    10. 字符常量的最大長度(字節數)<=32672
    11. 圖形常量的最大長度(字節數)<=16336
    12. 串聯字符串的最大長度(字節數)<=2147483647
    13. 串聯圖形串的最大長度(字節數)<=1073741823
    14. 串聯二進制串的最大長度(字節數)<=2147483647
    15. 十六進制常量數字的最大長度(字節數)<=16336
    16. 分類注釋的最大長度(字節數)<=254
    17. 運行時結构類型列對象的最大長度(字節數)<=1


    1. 最小的 INTEGER 值 >= -2147483648
    2. 最大的 INTEGER 值 <= 2147483648
    3. 最小的 BIGINT 值 >= -9223372036854775808
    4. 最大的 BIGINT 值 <= 9223372036854775808
    5. 最小的 SMALLINT 值 >= -32768
    6. 最大的 SMALLINT 值 <= 32768
    7. 最小的 十進制精度 <= 31
    8. 最小的 DOUBLE 值 >= -1.79769E+308
    9. 最大的 DOUBLE 值 <= 1.79769E+308
    10. 最小的正 DOUBLE 值 >= 2.225E-307
    11. 最大的負 DOUBLE 值 <= -2.225E-307
    12. 最小的 REAL 值 >= -3.402E+38
    13. 最大的 REAL 值 <= 3.402E+38
    14. 最小的正 REAL 值 >= 1.175E-37
    15. 最大的負 REAL 值 <= -1.175E-37

    星期四, 一月 18, 2007

    jdbc batch

    Description of batch updates
    6.1.1 StatementsThe batch update facility allows a Statement object to submit a set of heterogeneous update commands together as a single unit, or batch, to the underlying DBMS. In the example below all of the update operations required to insert a new employee into a fictitious company database are submitted as a single batch.

    // turn off autocommit
    con.setAutoCommit(false);
    Statement stmt = con.createStatement();
    stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe Jones')");
    stmt.addBatch("INSERT INTO departments VALUES (260, 'Shoe')");
    stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)");
    // submit a batch of update commands for execution
    int[] updateCounts = stmt.executeBatch();
    In the example, autocommit mode is disabled to prevent the driver from committing the transaction when Statement.executeBatch() is called. Disabling autocommit allows an application to decide whether or not to commit the transaction in the event that an error occurs and some of the commands in a batch cannot be processed successfully. For this reason, autocommit should always be turned off when batch updates are done. The commit behavior of executeBatch is always implementation defined when an error occurs and autocommit is true.
    To keep our discussion of batch updates general, we define the term element to refer to an individual member of a batch. As we have seen, an element in a batch is just a simple command when a Statement object is being used. Although we are focusing on using Statement objects to do batch updates in this section, the discussion that follows applies to PreparedStatment and CallableStatement objects, as well.
    In the new JDBC API, a Statement object has the ability to keep track of a list of commands -or batch-that can be submitted together for execution. When a Statement object is created, its associated batch is empty-the batch contains no elements. The Statement.addBatch() method adds an element to the calling statement's batch. The method Statement.clearBatch() (not shown above) can be called to reset a batch if the application decides not to submit a batch of commands that has been constructed for a statement.
    Successful execution
    The Statement.executeBatch() method submits a statement's batch to the underlying data source for execution. Batch elements are executed serially (at least logically) in the order in which they were added to the batch. When all of the elements in a batch execute successfully, executeBatch() returns an integer array containing one entry for each element in the batch. The entries in the array are ordered according to the order in which the elements were processed (which, again, is the same as the order in which the elements were originally added to the batch). An entry in the array may have the following values:

    If the value of an array entry is greater than or equal to zero, then the batch element was processed successfully and the value is an update count indicating the number of rows in the database that were effected by the element's execution.
    A value of -2 indicates that a element was processed successfully, but that the number of effected rows is unknown. Calling executeBatch() closes the calling Statement object's current result set if one is open. The statement's internal list of batch elements is reset to empty once executeBatch() returns. The behavior of the executeQuery, executeUpdate, or execute methods is implementation defined when a statement's batch is non-empty.
    ExecuteBatch() throws a BatchUpdateException if any of the elements in the batch fail to execute properly, or if an element attempts to return a result set. Only DDL and DML commands that return a simple update count may be executed as part of a batch. When a BatchUpdateException is thrown, the BatchUpdateException.getUpdateCounts() method can be called to obtain an integer array of update counts that describes the outcome of the batch execution.
    Handling failures during execution
    A JDBC driver may or may not continue processing the remaining elements in a batch once execution of an element in a batch fails. However, a JDBC driver must always provide the same behavior when used with a particular DBMS. For example, a driver cannot continue processing after a failure for one batch, and not continue processing for another batch.
    If a driver stops processing after the first failure, the array returned by BatchUpdateException.getUpdateCounts() will always contain fewer entries than there were elements in the batch. Since elements are executed in the order that they are added to the batch, if the array contains N elements, this means that the first N elements in the batch were processed successfully when executeBatch() was called.
    When a driver continues processing in the presence of failures, the number of elements, N, in the array returned by BatchUpdateException.getUpdateCounts()is always equal to the number of elements in the batch. The following additional array value is returned when a BatchUpdateException is thrown and the driver continues processing after a failure:

    A value of -3 indicates that the command or element failed to execute successfully. This value is also returned for elements that could not be processed for some reason-such elements fail implicitly. JDBC drivers that do not continue processing after a failure never return -3 in an update count array. Drivers of this type simply return a status array containing an entry for each command that was processed successfully.
    A JDBC technology based application can distinguish a JDBC driver that continues processing after a failure from one that does not by examining the size of the array returned by BatchUpdateException.getUpdateCounts(). A JDBC driver that continues processing always returns an array containing one entry for each element in the batch. A JDBC driver that does not continue processing after a failure will always return an array whose number of entries is less than the number of elements in the batch.

    6.1.2 PreparedStatementsAn element in a batch consists of a parameterized command and an associated set of parameters when a PreparedStatement is used. The batch update facility is used with a PreparedStatement to associate multiple sets of input parameter values with a single PreparedStatement object. The sets of parameter values together with their associated parameterized update command can then be sent to the underlying DBMS engine for execution as a single unit.
    The example below inserts two new employee records into a database as a single batch. The PreparedStatement.setXXX() methods are used to create each parameter set (one for each employee), while the PreparedStatement.addBatch() method adds a set of parameters to the current batch.

    // turn off autocommit
    con.setAutoCommit(false);
    PreparedStatement stmt = con.prepareStatement(
    "INSERT INTO employees VALUES (?, ?)");
    stmt.setInt(1, 2000);
    stmt.setString(2, "Kelly Kaufmann");
    stmt.addBatch();
    stmt.setInt(1, 3000);
    stmt.setString(2, "Bill Barnes");
    stmt.addBatch();

    // submit the batch for execution
    int[] updateCounts = stmt.executeBatch();
    Finally, PreparedStatement.executeBatch() is called to submit the updates to the DBMS. Calling PreparedStatement.executeBatch() clears the statement's associated list of batch elements. The array returned by PreparedStatement.executeBatch() contains an element for each set of parameters in the batch, similar to the case for Statement. Each element either contains an update count or the generic `success' indicator (-2).
    Error handling in the case of PreparedStatement objects is the same as error handling in the case of Statement objects. Some drivers may stop processing as soon as an error occurs, while others may continue processing the rest of the batch. As for Statement, the number of elements in the array returned by BatchUpdateException.getUpdateCounts() indicates whether or not the driver continues processing after a failure. The same three array element values are possible, as for Statement. The order of the entries in the array is the same order as the order in which elements were added to the batch.

    星期二, 一月 16, 2007

    使用jdbc4.0

    https://www6.software.ibm.com/developerworks/cn/education/opensource/os-ad-jdbc/index.html

    DBCon.java

    package common;
    import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;
    public class DBCon { public static Connection getConnection() { Connection con=null; String CLASSFORNAME="com.ibm.db2.jcc.DB2Driver"; //String CLASSFORNAME="com.ibm.db2.jdbc.app.DB2Driver"; String SERVANDDB="jdbc:db2://localhost:50000/test11"; String USER="db2admin"; String PWD="db2admin"; try { Class.forName(CLASSFORNAME).newInstance(); con = DriverManager.getConnection(SERVANDDB,USER,PWD); }catch(SQLException e){ System.out.println("aaaaa"); while(e != null) { System.out.print("SQL State: " +e.getSQLState()); System.out.print("Vendor Specific code: " +e.getErrorCode()); e = e.getNextException(); }
    System.out.println("bbbbbb"); } catch(Exception ex) { System.out.println("EX State: " +ex.getMessage()); System.out.println("WEX code: " +ex.getStackTrace()); } return con; }}

    星期三, 十月 18, 2006

    plsql读书笔记7----数字函数和字符函数

    1,数字函数
    ABS(n) 绝对值
    CEIL(n)大于等于n的最小整数,FLOOR(n)小于等于n的最小整数
    ACOS(n)反余弦,ASIN(n)反正弦,ATAN(n)反正切,ATAN2(n,m) n/m的反正切
    COS(n)余弦,COSH(n)双曲余弦,SIN(n)正弦,SINH(n)双曲正弦,TAN(n)正切,TANH(n)双曲正切
    EXP(n)e的n次幂,LN(n)n的自然对数,LOG(m,n)以m为底的n的对数
    MOD(m,n)m/n的余数
    POWER(m,n)m的n次幂
    SQRT(n)n的平方根
    ROUND(n,[m])四舍五入n到小数点后m位
    SIGN(n)监测n的正负
    TRUNC(n,[m])截取n到小数点后m位

    2,字符函数
    ASCII(char)返回字符串首字符的ASCII值
    CHR(n)返回ASCII码值的对应字符
    CONCAT连接字符串,等同于"||"
    INITCAP(char)单词首字符大写,NLS_INITCAP(char,'nls_param')单词首字符大写
    INSTR(char1,char2[,n[,m]])取得char2在char1中从第n个字符开始的第m次出现的位置
    LENGTH(char)字符串长度

    LOWER
    (char)转换为小写格式,NLS_LOWER(char,'nls_param')转换为小写格式
    LUPPER(char)转换为大写格式,NLS_UPPERER(char,'nls_param')转换为大写格式

    LPAD
    (char1,n,char2)在char1左端填充char2直至串长度是n
    RPAD(char1,n,char2)在char1右端填充char2直至串长度是n

    TRIM
    (charFROM string)从string头部,尾部,或者两端截去char
    LTRIM
    (char1[,set])去掉char1左端所包含的set中的任何字符,遇到不是set中字符结束。
    RTRIM(char1[,set])去掉char1右端所包含的set中的任何字符,遇到不是set中字符结束。

    SORT(char)排序,NLS_SORT(char,'nls_param')按特定语言要求排序,

    REPLACE
    (char,search_string[,replacement_string])将char中的search_string替换为replacement_string.
    REGEXP_REPLASE(sourse_string,pattern[,replace_string[,position[,occurrence[,match_parameter]]]])
    source_string 为源字符串,pattern为指定规则表达式,replace_string为替换字符串,position为起始搜索位置,occurrence用于指定替换出现的第几个字符串,match_parameter用于制定默认匹配操作的文本串。

    SUBSTR(char,m[,n])取得char的从m开始的n个字符的子串
    REGEXP_SUBSTR
    (sourse_string,pattern[,replace_string[,position[,occurrence[,match_parameter]]]])
    source_string 为源字符串,pattern为指定规则表达式,replace_string为替换字符串,position为起始搜索位置,occurrence用于指 定替换出现的第几个字符串,match_parameter用于制定默认匹配操作的文本串。

    SOUNDEX(char)返回字符串的语音表示,可用于比较发音相同的字符串。

    TRANSLATE(char,from_string,to_string)将char按照from_string到to_string的对应关系转换。

    ps:对于参数格式为(char,'nls_param')的,char用于指定NCHAR或NVACHAR2类型字符串,
    前边加n,用单引号括起来,nls_param的格式为“nls_sort=sort”,用于制定特定语言特征。

    星期二, 十月 17, 2006

    plsql读书笔记6----合并查询,复杂查询

    合并查询

    1, UNION,UNION ALL,INTERSECT,MINUS
    2,对LOB,VARRAY和嵌套表来说,集合操作符是无效的。
    对LONG列来说,UNION,INTERSECT,MINUS操作符是无效的。
    如果选择列表包含了表达式,必须为其指定列别名。
    3,UNION取得并集,去掉重复行,按第一列排序
    UNION ALL 取得并集,不去掉重复行,不排序
    INTERSECT取得交集,按第一列排序
    MINUS取得差集(存在于第一个表,但是不存在于第二个表),按第一列排序

    复杂查询

    1,层次查询
    START WITH:指定根行
    CONNECT BY:父子行之间关系,条件表达式中,使用FRIOR引用父行
    col emane format a15
    col job format a15
    SELECT LPAD('',3*(LEVEL-1))||ename ename,
    LPAD('',3*(LEVEL-1))||job job FROM emp
    WHERE job<>'CLERK' START WITH mgr IS NULL
    CONNECT BY mgr = PRIOR empno;

    2,CASE 表达式
    CASE
    WHEN case1 THEN option1
    WHEN case2 THEN option2
    ELSE case3
    END

    3,倒叙查询(Flashback Query)
    SELECT * FROM emp AS OF TIMESTAMP to_timestame(
    '2003-01-01 19:19:22','YYYY-MM-DD HH24:MI:SS')
    WHERE ename = 'tom'

    4,WITH子句
    WITH summary AS (
    SELECT dname,SUM(sal) AS dept_total FROM emp,dept
    WHERE emp.deptno = deept.deptno GROUP BY dname)

    SELECT dname,dept_total FROM summary WHERE dept_totle>
    (SELECT SUM(dept_total)*1/3 FROM summary);

    plsql读书笔记5----子查询

    1 ,匹配符
    "=",">","<","<>",IN,ALL,ANY
    其中,ALL,ANY必须跟单行比较符结合使用
    2,多列子查询

    3,相关子查询()??????????
    EXISTS
    SELECT ename ,job,sal,deptno FROM emp WHERE EXISTS
    (SELECT 1 FROM dept WHERE dept.deptno = emp.deptno
    AND dept.loc='NEW YORK');

    4,FROM 中使用子查询(内嵌视图)
    必须为子查询指定别名。
    SELECT ename,job,sal FROM emp,
    (SELECT deptno,avg(sal) avgsal FROM emp
    GROUP BY deptno) dept
    WHERE emp.deptno = dept.deptno AND sal>dept.avgsal;

    plsql读书笔记4

    in order to fill

    plsql读书笔记3

    in order to fill

    plsql读书笔记2

    1,BINARY_FLOAT 1.5f
    BINARY_DOUBLE 3.00005d

    2,identifier [CONSTANT] datatype [NOT NULL] [:= | DEFAULT expr]

    3,emp.ename%TYPE
    4,复合变量
    a,PL/SQL纪录
    DECLARE
    TYPE type_name IS RECORD(
    name emp.ename%TYPE,
    title emp.etitle%TYPE,
    );
    record_name typename;
    BEGIN
    SELECT ename,etitle INTO record_name
    FROM emp WHERE empno=42332;
    dbms_output.put_line('name'||emp_record.name);
    END;
    b,PL/SQL表
    下标没有上下限
    DECLARE
    TYPE type_name IS TABLE OF emp.ename%TYPE
    INDEX BY BINARY_INTEGER;
    table_name type_name;
    BEGIN
    SELECT ename INTO table_name(-1) FROM emp
    WHERE empno = 123;
    dbms_output.put_line('name'||table_name(-1));
    END;
    c,嵌套表(Nested Table)
    CREATE OR REPLACE TYPE type_name AS OBJECT(
    name VARCHER2(10), title NUMBER(6,2),date DATE);
    ps:使用嵌套表作为表列时应指定其存储表
    eg:NESTED TABLE nested_table STORE AS nested_table_name;
    d,VARRAY(变长数组)
    VARRAY的元素个数是有限制的
    CREATE TYPE type_name AS OBJECT(
    title VARCHER2(20),date DATE);

    CREATE TYPE varray_name IS VARRAY(20) OF type_name;

    plsql读书笔记1

    1,基本格式
    DECLARE
    BEGIN
    EXCEPTION
    END;
    2,PLSQL块分类
    1),匿名块
    2)命名块
    <<outer_name>>
    DECLARE
    BEGIN
    <<inner_name>>
    BEGIN
    END;--<<inner_name>>
    END;--<<outer_name>>
    3)子程序
    a,过程
    CREATE PROCEDURE procedure_name(name1 VARCHEAR2, name2 NUMBER)
    IS
    BEGIN
    END;
    调用过程时用命令:execute或者call
    b,函数
    CREATE FUNCTION function_name(name1 NUMBER,name2 VARCHAR2)
    RETURN NUMBER IS
    return_name NUMBER(7,2)
    BEGIN
    END;
    c,包
    CREATE PACKAGE page_name IS
    PROCEDURE procedure_name;
    FUNCTION function_name;
    END
    4,触发器
    CREATE TIGGER tigger_name
    AFTER UPDATE OF deptno ON dept
    FOR EACH ROW
    BEGIN 
    END;