2 zte1055889498 zte1055889498 于 2013.12.22 16:58 提问

尝试写了一个 JDBC 操作 SQLServer 的工具类,但是好像有问题,求大神帮忙指正

java新人,尝试写了一个 JDBC 操作 SQLServer 的工具类,但是好像有问题,调用 insert 指令没问题,而 select 指令出现如下报错:
com.microsoft.sqlserver.jdbc.SQLServerException: ')' 附近有语法错误。
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:216)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.getNextResult(SQLServerStatement.java:1515)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.doExecuteStatement(SQLServerStatement.java:792)
at com.microsoft.sqlserver.jdbc.SQLServerStatement$StmtExecCmd.doExecute(SQLServerStatement.java:689)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:5696)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1715)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeCommand(SQLServerStatement.java:180)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeStatement(SQLServerStatement.java:155)
at com.microsoft.sqlserver.jdbc.SQLServerStatement.executeQuery(SQLServerStatement.java:616)
at com.javaee.servletxm.comm.MSSQLJDBC.select(MSSQLJDBC.java:160)
at com.javaee.servletxm.comm.MSSQLJDBC.select(MSSQLJDBC.java:195)
at com.javaee.servletxm.comm.MSSQLJDBC.selectFirstValue(MSSQLJDBC.java:172)
at com.javaee.servletxm.comm.MSSQLJDBC.getPageNumber(MSSQLJDBC.java:221)
at com.javaee.servletxm.comm.MSSQLJDBC.selectByFY(MSSQLJDBC.java:259)
at com.javaee.servletxm.kqgl.KqManager.getAllKqxx(KqManager.java:38)
at com.javaee.servletxm.kqgl.Kqwh.doGet(Kqwh.java:47)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:879)
at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:617)
at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1760)
at java.lang.Thread.run(Thread.java:724)

这是具体的代码,求大神帮忙指正

package com.javaee.servletxm.comm;
/**

  • jdbc下 SQL Server 2005 数据库的封装类 */ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.Date; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.text.SimpleDateFormat; import java.util.List; import java.util.Properties;

public class MSSQLJDBC {
// 配置文件名称
private String iniFileName = MSSQLJDBC.class.getClassLoader().getResource("/com/javaee/servletxm/comm").getPath()+ "mssql.properties";
// 连接数据库
private String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
private String url = "jdbc:sqlserver://localhost;DatabaseName=jdms";
private String user = "sa";
private String password = "";

// 定义连接属性
private Connection connect = null;

// 与连接有关三个通道
private Statement stmt = null;
private PreparedStatement pstmt = null;
private CallableStatement cstmt = null;

public static final String stmtType = "stmt";
public static final String pstmtType = "pstmt";
public static final String cstmtType = "cstmt";

// 定义参数类型的静态常量值
public static final String varCharType = "varchar";
public static final String intType = "int";
public static final String doubleType = "decimal";
public static final String dateType = "datetime";
public static final String timeType = "timestamp";

// 定义全局的结果集
private ResultSet rs = null;

// 在构造方法中对属性进行初始化赋值操作
public MSSQLJDBC() {
    // 读取配置文件
    readIni();
    // 初始化连接
    initConnect();
}

// 可配置文件 .properties
// 读取配置文件
private void readIni() {
    File file = new File(iniFileName);
    if (!file.exists()) {
        // 创建一个文件
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    // 判断文件是否有值
    if (file.length() == 0) {// 说明是一个空文件
        // 初始化值
        try {
            Properties p = new Properties();
            p.put("driver", driver);
            p.put("url", url);
            p.put("user", user);
            p.put("password", password);
            FileOutputStream fos = new FileOutputStream(file);
            p.store(fos, "配置文件信息");
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    } else {// 如果有值
        // 将信息读取出来
        try {
            FileInputStream fis = new FileInputStream(file);
            Properties p = new Properties();
            p.load(fis);
            this.driver = p.getProperty("driver");
            this.url = p.getProperty("url");
            this.user = p.getProperty("user");
            this.password = p.getProperty("password");
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

// 建立连接
private void initConnect() {
    try {
        Class.forName(driver);
        this.connect = DriverManager.getConnection(url, user, password);
        this.connect.setAutoCommit(false);// 设置手动提交事务
        this.stmt = connect.createStatement();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

/*/ 从tomcat缓冲池获取连接
private void initConnectFromDataSource() {
    try {
        InitialContext ic = new InitialContext();
        DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/oracleds");
        this.connect = ds.getConnection();
        this.connect.setAutoCommit(false);
        this.stmt = connect.createStatement();
    } catch (NamingException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}*/

// 需要调用者控制事务的两个方法
// 提交方法
private void commit() {
    try {
        this.connect.commit();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

// 回滚事务
private void rollBack() {
    try {
        this.connect.rollback();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

// 定义一组与操作有关的方法
// 使用普通通道执行的select
public ResultSet select(String sql) {
    ResultSet prs = null;
    if (stmt != null) {
        try {
            prs = stmt.executeQuery(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return prs;
}

// 根据传入的sql直接获取单一值
// 使用此方法的时候sql语句返回的单一的值
public String selectFirstValue(String sql, String type, List<String> csList) {
    String rstr = "";
    rs = select(sql, type, csList);// 确定此结果集只有一条记录
    if (rs != null) {// 说明结果集有值,且只有一条记录
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            if (rs.next()) { // 移动到第一条记录
                String p_type = rsmd.getColumnTypeName(1);
                rstr = getResultSetValue(rs, 1, p_type);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return rstr;
}

// 使用普通通道执行的select
/**
 * sql 参数 type 使用通道的类型 stmt pstmt cstmt List<String> csList 预编通道执行的参数队列
 * String 最少必须满足如下条件的字符串 数据类型 ,数据值 数据类型定义说明 字符串 数字(整数、小数) 日期(DATE、TIMESTAMP)
 */
public ResultSet select(String sql, String type, List<String> csList) {
    ResultSet prs = null;
    if (type.equals(stmtType)) {// 说明使用普通通道来执行
        prs = select(sql);
    } else if (type.equals(pstmtType)) {// 说明使用预编译通道来执行
        if (connect != null) {
            try {
                pstmt = connect.prepareStatement(sql);
                // 验证传入的参数和sql中的参数个数一致

                setPrepareStatement(pstmt, csList);// 将参数设置进当前的预编译通道

                prs = pstmt.executeQuery();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    return prs;
}

// 获取 总页数
public int getPageNumber(String sql, String type, List<String> csList,
        int pageSize) {
    // 处理总页数
    int pageNumber = 0;

    // 第一步获取sql总记录数
    String psql = "select count(*) from (" + sql + ")";
    String result = selectFirstValue(psql, type, csList);
    int rows = 0;
    if (result != null && result.trim() != "") {
        rows = Integer.valueOf(result);
    }

    if (rows % pageSize == 0) {
        pageNumber = rows / pageSize;
    } else {
        pageNumber = rows / pageSize + 1;
    }
    return pageNumber;
}

/**
 * 自动添加分页查询方法
 * 
 * @param sql
 *            要执行的sql
 * @param type
 *            执行方式
 * @param csList
 *            参数列表
 * @param curPage
 *            当前页数
 * @param pageSize
 *            每页记录数 默认为10
 * @return
 */
public ResultSet selectByFY(String sql, String type, List<String> csList,
        int curPage, int pageSize) {
    ResultSet prs = null;

    // 处理 每页记录数
    if (pageSize <= 0) {
        pageSize = 10;// 默认页面10条记录
    }

    int pageNumber = getPageNumber(sql, type, csList, pageSize);

    // 处理当前页数
    if (curPage < 0) {
        curPage = 1;// 默认第一页
    }
    if (curPage > pageNumber) {
        curPage = pageNumber;
    }

    String psql = "select tmpaa.* from (select tmpa.*,(select (ROW_NUMBER() over (order by id))) as rn from ("
            + sql + ") tmpa where (select (ROW_NUMBER() over (order by id))) <= " + (curPage * pageSize)
            + ") tmpaa where tmpaa.rn >= " + ((curPage - 1) * pageSize + 1);
    prs = select(psql, type, csList);

    return prs;
}

// 将预编通道执行的参数队列按照指定规则设置进通道中
private void setPrepareStatement(PreparedStatement p, List<String> csList)
        throws Exception {
    if (csList != null && csList.size() > 0) {
        for (int i = 0; i < csList.size(); i++) {
            // 此处的str是数据类型 ,数据值
            // 解析出数据类型和数据值
            String[] s = csList.get(i).split(",");
            String sType = s[0];
            String sData = s[1];
            if (varCharType.equals(sType)) {
                p.setString(i + 1, sData);
            } else if (intType.equals(sType)) {
                p.setInt(i + 1, Integer.valueOf(sData));
            } else if(doubleType.equals(sType)){
                p.setDouble(i+1, Double.valueOf(sData));
            } else if (dateType.equals(sType)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
                java.util.Date d = sdf.parse(sData);
                p.setDate(i + 1, new Date(d.getTime()));
            } else if (timeType.equals(sType)) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-mm-dd");
                java.util.Date d = sdf.parse(sData);
                p.setTimestamp(i + 1, new Timestamp(d.getTime()));
            }
        }
    }
}

// 定义一个执行insert update delete的方法
public int iudSql(String sql) {
    int ri = -1;
    if (stmt != null) {
        try {
            ri = stmt.executeUpdate(sql);
            commit();
        } catch (SQLException e) {
            e.printStackTrace();
            rollBack();
        }
    }
    return ri;
}

public int iudSql(String sql, String type, List<String> csList) {
    int ri = -1;
    if (stmtType.equals(type)) {
        ri = iudSql(sql);
    } else if (pstmtType.equals(type)) {
        if (connect != null) {
            try {
                pstmt = connect.prepareStatement(sql);
                setPrepareStatement(pstmt, csList);
                ri = pstmt.executeUpdate();
                commit();
            } catch (Exception e) {
                e.printStackTrace();
                rollBack();
            }
        }
    }
    return ri;
}

/**
 * 编写一个通用的遍历ResultSet结果集的方法
 */
public void iteratorResultSet(ResultSet rs) {
    try {
        if (rs != null) {// 说明有值
            // ResultSetMetaData 此对象里封装了与结果集有关所有信息
            // 此结果有几列组成,每列的列名,每列的数据类型
            ResultSetMetaData rsmd = rs.getMetaData();
            // 得到结果集列数
            int columnCount = rsmd.getColumnCount();
            // 输出此结果集的所有列名
            for (int i = 1; i <= columnCount; i++) {
                System.out.print(rsmd.getColumnName(i) + "\t");
            }
            System.out.println("");
            // 遍历输出所有的数据
            while (rs.next()) {
                // 如何在获取rs中的数据?
                for (int i = 1; i <= columnCount; i++) {
                    String type = rsmd.getColumnTypeName(i);
                    System.out.print(getResultSetValue(rs, i, type) + "\t");
                }
                System.out.println("");
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

// 从ResultSet中根据数据类型来得到数据值的方法
// 先处理常用的sqlserver的数据类型的对应
private String getResultSetValue(ResultSet rs, int index, String type) {
    String rstr = "";
    try {
        if (rs != null && !"".equals(type) && index > 0) {
            if ("char".equals(type.trim()) || "varchar".equals(type.trim())) {
                if (rs.getString(index) != null) {
                    rstr = rs.getString(index);
                }
            } else if ("int".equals(type.trim())) {
                    rstr = rs.getInt(index) + "";
            } else if ("decimal".equals(type.trim())) {
                    rstr = String.valueOf(rs.getDouble(index));
            } else if ("date".equals(type.trim())) {
                Date date = rs.getDate(index);
                if (date != null) {
                    rstr = new SimpleDateFormat("yyyy年MM月dd日").format(date);
                }
            } else if ("timestamp".equals(type.trim()) || "datetime".equals(type.trim())) {
                Timestamp tt = rs.getTimestamp(index);
                if (tt != null) {
                    rstr = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(tt);
                }
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return rstr;
}

/*
//统一事务管理的批量sql的封装 
public boolean iudSql(List<String> sqlList){ 
    int ri = -1; 
    if(stmt!=null){ 
        try { 
            ri = stmt.executeUpdate(sql); 
            commit(); 
        } catch (SQLException e) { 
            e.printStackTrace(); 
            rollBack(); 
        } 
    } 
    return ri; 
}*/


// 关闭连接
public void close() {
    try {
        // 关闭所有的与数据库有关的对象
        if (rs != null) {
            rs.close();
            rs = null;
        }
        if (stmt != null) {
            stmt.close();
            stmt = null;
        }
        if (pstmt != null) {
            pstmt.close();
            pstmt = null;
        }
        if (cstmt != null) {
            cstmt.close();
            cstmt = null;
        }
        if (connect != null) {
            connect.close();
            connect = null;
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

}

1个回答

qwuack
qwuack   2014.06.28 20:32

-_-!
查询语句有问题
每次执行sql前把sql语句打印出来,仔细排查下

Csdn user default icon
上传中...
上传图片
插入图片