public void tableChanged(TableModelEvent e) { 
System.out.println(e.getFirstRow() + ":" + e.getColumn()); 
//e.getColumn() == -1,表示插入新行,在后面可以写对新行的操作,这里就不废话了 
if (e.getColumn() != -1) { 
Object o; 
//这两列是几个费用,修改后更新总费用和几个判断 
if (e.getColumn() == 3 || e.getColumn() == 6|| e.getColumn() == 9|| e.getColumn() == 10) { 
//获取某个格的数据 
o = tabData.getValueAt(e.getFirstRow(), 3); 
double b = 0.00; 
b =Double.valueOf(o.toString()); 
System.out.println(b); 
double a = 0.00; 
//空检查很重要 
if (o != null) { 
a =Double.valueOf(o.toString()); 

o = tabData.getValueAt(e.getFirstRow(), 6); 
double c = 0.00; 
c =Double.valueOf(o.toString()); 
System.out.println(c); 
if (o != null) { 
a += Double.valueOf(o.toString()); 

o = tabData.getValueAt(e.getFirstRow(), 9); 
double d = 0.00; 
d =Double.valueOf(o.toString()); 
System.out.println(d); 
if (o != null) { 
a += Double.valueOf(o.toString()); 

o = tabData.getValueAt(e.getFirstRow(), 10); 
if (o != null) { 
a += Double.valueOf(o.toString()); 

System.out.println(a); 
//设置某个格的数据 
//tabData.setValueAt(b, e.getFirstRow(), 3); 
//tabData.setValueAt(c, e.getFirstRow(), 6); 
//tabData.setValueAt(d, e.getFirstRow(), 9); 
tabData.setValueAt(a, e.getFirstRow(), 11); 
//boolean b = a >= 120; 
//tabData.setValueAt(b, e.getFirstRow(), 12); 

o = tabData.getValueAt(e.getFirstRow(), 0); 
if (o != null||rs!=null) { 
            { 
                //转换到模型行 
                int select = e.getFirstRow(); 
                if (select == -1) 
                { 
                    return; 
                } 
                select = tabData.getRowSorter().convertRowIndexToModel(select); 
                try 
                { 
                rs.beforeFirst(); 
                    rs.absolute(select + 1); 
                    //更新数据集中某个位置的内容 
                    rs.updateObject(e.getColumn() + 1, tabData.getValueAt(e.getFirstRow(), e.getColumn())); 
                    //将内容更新到数据库 
                    rs.updateRow();                  
                    //rs.close(); 
                } catch (SQLException ex) 
                { 
                    Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex); 
                } 
            } 
        } 
        //执行以后报诸如下面这样的错误但有时是可以运行并且不报错的。 
2009-10-13 17:54:52 SQLC.ConnectionSQL tableChanged 
严重: null 
java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC]Row update failed. 
at com.microsoft.jdbc.base.BaseExceptions.createException(Unknown Source)

解决方案 »

  1.   

    看你的rs應該是寫在Class里的全局變量。
    ConnectionSQL tableChanged 連接SQL的表被改變了。
    是不是你這個類的其他mothed把rs改變了?
      

  2.   

    package SQLC;import java.sql.*;
    import java.util.*;
    import java.util.logging.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    public class ConnectionSQL extends javax.swing.JFrame implements TableModelListener
    {
        //连接字符串
        String connectionUrl = "jdbc:sqlserver://localhost:1433;" +
                "databaseName=WYMS;user=sa;password=123456;";
        Connection con;
        Statement stmt;
        ResultSet rs;
        ResultSetMetaData rsm;
        String[] columnNames = null;    //列标题
        Object[][] data = null;         //数据项
        DefaultTableModel model;        //表格模型
        JLabel label = null; //显示修改字段位置
        /** Creates new form ConnectionSQL */
        public ConnectionSQL()
        {        initComponents();
            this.setLocationRelativeTo(null);    }       //<editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
        private void initComponents() {        cmdConnection = new javax.swing.JButton();
            jScrollPane1 = new javax.swing.JScrollPane();
            tabData = new javax.swing.JTable();
            cmdAddRow = new javax.swing.JButton();
            cmdDelRow = new javax.swing.JButton();
            cmdClose = new javax.swing.JButton();        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
            setTitle("SQL 操作实例  --By Null");        cmdConnection.setText("连接/显示");
            cmdConnection.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdConnectionActionPerformed(evt);
                }
            });        tabData.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null},
                    {null, null, null, null}
                },
                new String [] {
                    "Title 1", "Title 2", "Title 3", "Title 4", "Title 5", "Title6", "Title7", "Title8", "Title 9", "Title10", "Title11", "Title12"
                }
            ));
            jScrollPane1.setViewportView(tabData);        cmdAddRow.setText("添加行");
            cmdAddRow.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdAddRowActionPerformed(evt);
                }
            });        cmdDelRow.setText("删除行");
            cmdDelRow.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdDelRowActionPerformed(evt);
                }
            });        cmdClose.setText("关闭");
            cmdClose.addActionListener(new java.awt.event.ActionListener() {
                public void actionPerformed(java.awt.event.ActionEvent evt) {
                    cmdCloseActionPerformed(evt);
                }
            });        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
            getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addGap(6, 6, 6)
                    .addComponent(cmdConnection)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(cmdAddRow)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(cmdDelRow)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(cmdClose, javax.swing.GroupLayout.PREFERRED_SIZE, 66, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addContainerGap(203, Short.MAX_VALUE))
                .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 918, Short.MAX_VALUE)
            );
            layout.setVerticalGroup(
                layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(cmdConnection)
                        .addComponent(cmdAddRow)
                        .addComponent(cmdDelRow)
                        .addComponent(cmdClose))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 272, Short.MAX_VALUE))
            );        pack();
        }
      

  3.   

    private void cmdConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdConnectionActionPerformed
    // TODO add your handling code here:
        //连接并初始化表格
        try
        {
            //获取驱动,这里使用的是 sqljdbc_1.2.2828.100_chs.exe,不同版本的驱动,语句有所不同
         Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
        } catch (ClassNotFoundException ex)
        {
            Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
        }    try
        {String username="sa";
    String password="123456";
    con = DriverManager.getConnection(connectionUrl,username,password);
            //设置数据集可以滚动,可以更新
            stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
            //查询语句
            rs = stmt.executeQuery("SELECT fang_number,yuefen,j_type,wuye_money,b_shui_ds,shui_ds,shui_money,b_dian_ds,dian_ds,dian_money,zn_money,count_money from shoufeiInformation");
            rsm = rs.getMetaData();
            //判断时候可以实现对数据库的更新
            if (rs.getConcurrency() == ResultSet.CONCUR_UPDATABLE)
            {
                System.out.println("Can UPDATABLE");
            } else
            {
                System.out.println("Only Ready");
            }
            //获取列标题
            columnNames = new String[rsm.getColumnCount()];
            for (int i = 0; i < rsm.getColumnCount(); i++)
            {
                columnNames[i] = rsm.getColumnName(i + 1);
            }        int row = 0;
            int colum = 0;
            int columCount = rsm.getColumnCount();
            //获取行数,没有直接的方法,这里先移动到纪录结尾,获取行号,即为行数,然后再移回来
            rs.last();
            int rowCount = rs.getRow();
            rs.beforeFirst();        //读取数据到数据项变量
            data = new Object[rowCount][columCount];
            while (rs.next())
            {
                for (colum = 0; colum < rsm.getColumnCount(); colum++)
                {
                    data[row][colum] = rs.getObject(colum + 1);
                }
                row++;
            }
      
        } catch (SQLException ex)
        {
            Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
        }    //初始化数据模型
        model = new DefaultTableModel(data, columnNames)
        {        /**
     * 
     */
    private static final long serialVersionUID = 1L; /**
             * 重写 getColumnClass
             * 可以使表格自动识别数据类型
             */
            @Override
            public Class getColumnClass(int c)
            {
                //这里要对空数据集进行检验
                if (dataVector.isEmpty() == false && getValueAt(0, c)!=null)
                {
                    return getValueAt(0, c).getClass();
                } else
                {
                    return Object.class;
                }        }
        };
        //记得 implements TableModelListener,才能获取 tableChanged(TableModelEvent e) 事件
        model.addTableModelListener(this);
        //设置表格的模型
        tabData.setModel(model);
        //单击标题栏排序,如果需要排序,这个少不了
        RowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
        tabData.setRowSorter(sorter);    /*
         * 设置编辑器
         */
        /**JComboBox c = new JComboBox();
        c.addItem("工资");
        c.addItem("现金");
        
        tabData.getColumnModel().getColumn(1).setCellEditor(new DefaultCellEditor(c));*/
    }//GEN-LAST:event_cmdConnectionActionPerformedprivate void cmdAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdAddRowActionPerformed
        //添加新行
        try
        {
            //在数据模型中加入一个空的 Vector,就能实现空行的显示
            model.addRow(new Vector<Object>());
            //数据集的添加
            rs.moveToInsertRow();
            //初始化行数据,这里我的第一列是 非空的,所以随机产生一个数据
            //现实使用的时候可以弹出对话框要求用户输入,或者写一个新建,让用户输入完数据后一次插入
            rs.updateObject(1, (int) (System.currentTimeMillis() % 10000));
            //将新行写到数据库
            rs.insertRow();    } catch (SQLException ex)//GEN-LAST:event_cmdAddRowActionPerformed
            {
                Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
            }
        }private void cmdDelRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdDelRowActionPerformed
        //由于使用了排序,当前选择的行和数据集中对应的行可能序号不同
        //需要转换一下,看如下代码
        int select = tabData.getSelectedRow();
        if (select == -1)
        {
            return;
        }
        //转换表格选择的行号到数据模型的行号
        select = tabData.getRowSorter().convertRowIndexToModel(select);
        try
        {
            //定位到绝对行号,这个的内容和数据模型同步
            rs.absolute(select + 1);
            rs.deleteRow();
            model.removeRow(select);    } catch (SQLException ex)//GEN-LAST:event_cmdDelRowActionPerformed
            {
                Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
            }
        }private void cmdCloseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cmdCloseActionPerformed
        try
        {
            //关闭连接拉,
            rs.close();
            stmt.close();
            con.close();
        } catch (SQLException ex)
        {
            Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
        }}//GEN-LAST:event_cmdCloseActionPerformed    /**
        * @param args the command line arguments
         */
        public static void main(String args[])
        {
            java.awt.EventQueue.invokeLater(new Runnable()
            {            public void run()
                {
                    try
                    {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (Exception e)
                    {
                    }
                    new ConnectionSQL().setVisible(true);
                }
            });
        }    // Variables declaration - do not modify//GEN-BEGIN:variables
        private javax.swing.JButton cmdAddRow;
        private javax.swing.JButton cmdClose;
        private javax.swing.JButton cmdConnection;
        private javax.swing.JButton cmdDelRow;
        private javax.swing.JScrollPane jScrollPane1;
        private javax.swing.JTable tabData;
        // End of variables declaration//GEN-END:variables
        public void tableChanged(TableModelEvent e) {
    System.out.println(e.getFirstRow() + ":" + e.getColumn());
    //e.getColumn() == -1,表示插入新行,在后面可以写对新行的操作,这里就不废话了
    if (e.getColumn() != -1) {
    Object o;
    //这两列是4个费用,修改后更新总分和几个判断
    if (e.getColumn() == 3 || e.getColumn() == 6|| e.getColumn() == 9|| e.getColumn() == 10) {
    //获取某个格的数据
    o = tabData.getValueAt(e.getFirstRow(), 3);
    //double b = 0;
    //b =Double.valueOf(o.toString());
    //System.out.println(b);
    double a = 0;
    //空检查很重要
    if (o != null) {
    a =Double.valueOf(o.toString());
    }
    o = tabData.getValueAt(e.getFirstRow(), 6);
    //double c = 0;
    //c =Double.valueOf(o.toString());
    //System.out.println(c);
    if (o != null) {
    a += Double.valueOf(o.toString());
    }
    o = tabData.getValueAt(e.getFirstRow(), 9);
    //double d = 0;
    //d =Double.valueOf(o.toString());
    //System.out.println(d);
    if (o != null) {
    a += Double.valueOf(o.toString());
    }
    o = tabData.getValueAt(e.getFirstRow(), 10);
    if (o != null) {
    a += Double.valueOf(o.toString());
    }
    System.out.println(a);
    //设置某个格的数据
    //tabData.setValueAt(b, e.getFirstRow(), 3);
    //tabData.setValueAt(c, e.getFirstRow(), 6);
    //tabData.setValueAt(d, e.getFirstRow(), 9);
    tabData.setValueAt(a, e.getFirstRow(), 11);
    //boolean b = a >= 120;
    //tabData.setValueAt(b, e.getFirstRow(), 12);
    }
    o = tabData.getValueAt(e.getFirstRow(), 0);
    if (o != null||rs!=null) {
                {
                    //转换到模型行
                    int select = e.getFirstRow();
                    if (select == -1)
                    {
                        return;
                    }
                    select = tabData.getRowSorter().convertRowIndexToModel(select);
                    try
                    {
                     rs.beforeFirst();
                        rs.absolute(select + 1);
                        //更新数据集中某个位置的内容
                        rs.updateObject(e.getColumn() + 1, tabData.getValueAt(e.getFirstRow(), e.getColumn()));
                        //将内容更新到数据库
                        rs.updateRow();                  
                       // rs.close();
                    } catch (SQLException ex)
                    {
                        Logger.getLogger(ConnectionSQL.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
            
        }    }
    }